introduce Inc

This commit is contained in:
Folkert 2020-08-01 22:58:29 +02:00
parent 5548bf136d
commit a8bfd90a50
4 changed files with 81 additions and 23 deletions

View File

@ -348,7 +348,6 @@ pub fn build_expr<'a, 'ctx, 'env>(
.left()
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
}
LoadWithoutIncrement(_symbol) => todo!("implement load without increment"),
Load(symbol) => load_symbol(env, scope, symbol),
Str(str_literal) => {
if str_literal.is_empty() {
@ -655,6 +654,31 @@ pub fn build_expr<'a, 'ctx, 'env>(
}
RunLowLevel(op, args) => run_low_level(env, layout_ids, scope, parent, *op, args),
Inc(symbol, expr) => {
match scope.get(symbol) {
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
Some((layout, ptr)) => {
match layout {
Layout::Builtin(Builtin::List(Ownership::Owned, _elem_layout)) => {
let load = env
.builder
.build_load(*ptr, symbol.ident_string(&env.interns));
let wrapper_struct = env
.builder
.build_load(*ptr, symbol.ident_string(&env.interns))
.into_struct_value();
increment_refcount_list(env, wrapper_struct, load)
}
_ => {
// not refcounted, do nothing special
build_expr(env, layout_ids, scope, parent, expr)
}
}
}
}
}
DecAfter(symbol, expr) => {
match scope.get(symbol) {
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
@ -817,23 +841,9 @@ fn load_symbol<'a, 'ctx, 'env>(
symbol: &Symbol,
) -> BasicValueEnum<'ctx> {
match scope.get(symbol) {
Some((layout, ptr)) => match layout {
Layout::Builtin(Builtin::List(Ownership::Owned, _)) => {
let load = env
.builder
.build_load(*ptr, symbol.ident_string(&env.interns));
let wrapper_struct = env
.builder
.build_load(*ptr, symbol.ident_string(&env.interns))
.into_struct_value();
increment_refcount_list(env, wrapper_struct, load)
}
_ => env
.builder
.build_load(*ptr, symbol.ident_string(&env.interns)),
},
Some((_, ptr)) => env
.builder
.build_load(*ptr, symbol.ident_string(&env.interns)),
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
}
}

View File

@ -322,7 +322,7 @@ pub enum Expr<'a> {
Store(&'a [(Symbol, Layout<'a>, Expr<'a>)], &'a Expr<'a>),
/// RC instructions
LoadWithoutIncrement(Symbol),
Inc(Symbol, &'a Expr<'a>),
DecAfter(Symbol, &'a Expr<'a>),
// Functions

View File

@ -156,7 +156,7 @@ pub fn function_r<'a>(env: &mut Env<'a, '_>, body: &'a Expr<'a>) -> Expr<'a> {
| Byte(_)
| Load(_)
| EmptyArray
| LoadWithoutIncrement(_)
| Inc(_, _)
| FunctionPointer(_, _)
| RuntimeError(_)
| RuntimeErrorFunction(_) => body.clone(),
@ -334,7 +334,7 @@ fn function_s<'a>(
| Byte(_)
| Load(_)
| EmptyArray
| LoadWithoutIncrement(_)
| Inc(_, _)
| FunctionPointer(_, _)
| RuntimeError(_)
| RuntimeErrorFunction(_) => Err(body),
@ -352,7 +352,7 @@ fn symbols_in_expr<'a>(initial: &Expr<'a>) -> MutSet<Symbol> {
while let Some(expr) = stack.pop() {
match expr {
FunctionPointer(symbol, _) | LoadWithoutIncrement(symbol) | Load(symbol) => {
FunctionPointer(symbol, _) | Load(symbol) => {
result.insert(*symbol);
}
@ -417,7 +417,7 @@ fn symbols_in_expr<'a>(initial: &Expr<'a>) -> MutSet<Symbol> {
stack.push(body)
}
DecAfter(symbol, body) => {
DecAfter(symbol, body) | Inc(symbol, body) => {
result.insert(*symbol);
stack.push(body);
}

View File

@ -1027,4 +1027,52 @@ mod test_mono {
),
)
}
#[test]
fn is_nil() {
compiles_to_string(
r#"
isNil = \xs ->
when xs is
Nil -> True
Cons _ _ -> False
isNil Nil
"#,
indoc!(
r#"
procedure Test.0 (Test.2):
Store Test.2: Load Test.2
Store Test.3: Lowlevel.And (Lowlevel.Eq true (Load Test.2)) true
if Test.3 then
true
else
false
Dec Test.2
Call Test.0 true
"#
),
)
}
#[test]
fn y_is_dead() {
compiles_to_string(
r#"
f = \y -> Pair y y
f [1]
"#,
indoc!(
r#"
procedure Test.0 (Test.2):
Struct [(Load(`Test.y`), Builtin(List(Owned, Builtin(Int64)))), (Load(`Test.y`), Builtin(List(Owned, Builtin(Int64))))]
Dec Test.2
Call Test.0 [ 1i64 ]
"#
),
)
}
}