mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
introduce Inc
This commit is contained in:
parent
5548bf136d
commit
a8bfd90a50
4 changed files with 81 additions and 23 deletions
|
@ -348,7 +348,6 @@ pub fn build_expr<'a, 'ctx, 'env>(
|
||||||
.left()
|
.left()
|
||||||
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
|
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
|
||||||
}
|
}
|
||||||
LoadWithoutIncrement(_symbol) => todo!("implement load without increment"),
|
|
||||||
Load(symbol) => load_symbol(env, scope, symbol),
|
Load(symbol) => load_symbol(env, scope, symbol),
|
||||||
Str(str_literal) => {
|
Str(str_literal) => {
|
||||||
if str_literal.is_empty() {
|
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),
|
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) => {
|
DecAfter(symbol, expr) => {
|
||||||
match scope.get(symbol) {
|
match scope.get(symbol) {
|
||||||
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
|
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
|
||||||
|
@ -817,23 +841,9 @@ fn load_symbol<'a, 'ctx, 'env>(
|
||||||
symbol: &Symbol,
|
symbol: &Symbol,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
match scope.get(symbol) {
|
match scope.get(symbol) {
|
||||||
Some((layout, ptr)) => match layout {
|
Some((_, ptr)) => env
|
||||||
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
|
.builder
|
||||||
.build_load(*ptr, symbol.ident_string(&env.interns)),
|
.build_load(*ptr, symbol.ident_string(&env.interns)),
|
||||||
},
|
|
||||||
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
|
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>),
|
Store(&'a [(Symbol, Layout<'a>, Expr<'a>)], &'a Expr<'a>),
|
||||||
|
|
||||||
/// RC instructions
|
/// RC instructions
|
||||||
LoadWithoutIncrement(Symbol),
|
Inc(Symbol, &'a Expr<'a>),
|
||||||
DecAfter(Symbol, &'a Expr<'a>),
|
DecAfter(Symbol, &'a Expr<'a>),
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
|
|
|
@ -156,7 +156,7 @@ pub fn function_r<'a>(env: &mut Env<'a, '_>, body: &'a Expr<'a>) -> Expr<'a> {
|
||||||
| Byte(_)
|
| Byte(_)
|
||||||
| Load(_)
|
| Load(_)
|
||||||
| EmptyArray
|
| EmptyArray
|
||||||
| LoadWithoutIncrement(_)
|
| Inc(_, _)
|
||||||
| FunctionPointer(_, _)
|
| FunctionPointer(_, _)
|
||||||
| RuntimeError(_)
|
| RuntimeError(_)
|
||||||
| RuntimeErrorFunction(_) => body.clone(),
|
| RuntimeErrorFunction(_) => body.clone(),
|
||||||
|
@ -334,7 +334,7 @@ fn function_s<'a>(
|
||||||
| Byte(_)
|
| Byte(_)
|
||||||
| Load(_)
|
| Load(_)
|
||||||
| EmptyArray
|
| EmptyArray
|
||||||
| LoadWithoutIncrement(_)
|
| Inc(_, _)
|
||||||
| FunctionPointer(_, _)
|
| FunctionPointer(_, _)
|
||||||
| RuntimeError(_)
|
| RuntimeError(_)
|
||||||
| RuntimeErrorFunction(_) => Err(body),
|
| RuntimeErrorFunction(_) => Err(body),
|
||||||
|
@ -352,7 +352,7 @@ fn symbols_in_expr<'a>(initial: &Expr<'a>) -> MutSet<Symbol> {
|
||||||
|
|
||||||
while let Some(expr) = stack.pop() {
|
while let Some(expr) = stack.pop() {
|
||||||
match expr {
|
match expr {
|
||||||
FunctionPointer(symbol, _) | LoadWithoutIncrement(symbol) | Load(symbol) => {
|
FunctionPointer(symbol, _) | Load(symbol) => {
|
||||||
result.insert(*symbol);
|
result.insert(*symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,7 +417,7 @@ fn symbols_in_expr<'a>(initial: &Expr<'a>) -> MutSet<Symbol> {
|
||||||
stack.push(body)
|
stack.push(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
DecAfter(symbol, body) => {
|
DecAfter(symbol, body) | Inc(symbol, body) => {
|
||||||
result.insert(*symbol);
|
result.insert(*symbol);
|
||||||
stack.push(body);
|
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…
Add table
Add a link
Reference in a new issue