mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 00:09:33 +03:00
introduce Inc
This commit is contained in:
parent
5548bf136d
commit
a8bfd90a50
@ -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),
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 ]
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user