mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
insert inc and dec instructions
This commit is contained in:
parent
fc52bdc59a
commit
b716636db0
2 changed files with 37 additions and 4 deletions
|
@ -717,6 +717,9 @@ pub fn build_expr<'a, 'ctx, 'env>(
|
||||||
todo!("LLVM build runtime error of {:?}", expr);
|
todo!("LLVM build runtime error of {:?}", expr);
|
||||||
}
|
}
|
||||||
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),
|
||||||
|
|
||||||
|
IncBefore(_, expr) => build_expr(env, layout_ids, scope, parent, expr),
|
||||||
|
DecAfter(_, expr) => build_expr(env, layout_ids, scope, parent, expr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -352,6 +352,10 @@ pub enum Expr<'a> {
|
||||||
},
|
},
|
||||||
EmptyArray,
|
EmptyArray,
|
||||||
|
|
||||||
|
/// RC instructions
|
||||||
|
IncBefore(Symbol, &'a Expr<'a>),
|
||||||
|
DecAfter(Symbol, &'a Expr<'a>),
|
||||||
|
|
||||||
RuntimeError(&'a str),
|
RuntimeError(&'a str),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,12 +604,20 @@ fn from_can<'a>(
|
||||||
layout_cache,
|
layout_cache,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Expr::Load(symbol)
|
Expr::IncBefore(symbol, env.arena.alloc(Expr::Load(symbol)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LetRec(defs, ret_expr, _, _) => from_can_defs(env, defs, *ret_expr, layout_cache, procs),
|
LetRec(defs, ret_expr, _, _) => from_can_defs(env, defs, *ret_expr, layout_cache, procs),
|
||||||
LetNonRec(def, ret_expr, _, _) => {
|
LetNonRec(def, ret_expr, _, _) => {
|
||||||
from_can_defs(env, vec![*def], *ret_expr, layout_cache, procs)
|
let symbols = roc_can::pattern::symbols_from_pattern(&def.loc_pattern.value);
|
||||||
|
let mut result = from_can_defs(env, vec![*def], *ret_expr, layout_cache, procs);
|
||||||
|
|
||||||
|
// TODO is order important here?
|
||||||
|
for symbol in symbols {
|
||||||
|
result = Expr::DecAfter(symbol, env.arena.alloc(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
Closure(ann, name, _, loc_args, boxed_body) => {
|
Closure(ann, name, _, loc_args, boxed_body) => {
|
||||||
|
@ -1208,6 +1220,13 @@ fn from_can_when<'a>(
|
||||||
let arena = env.arena;
|
let arena = env.arena;
|
||||||
let mut stored = Vec::with_capacity_in(1, arena);
|
let mut stored = Vec::with_capacity_in(1, arena);
|
||||||
|
|
||||||
|
let bound_symbols = first
|
||||||
|
.patterns
|
||||||
|
.iter()
|
||||||
|
.map(|pat| roc_can::pattern::symbols_from_pattern(&pat.value))
|
||||||
|
.flatten()
|
||||||
|
.collect::<std::vec::Vec<_>>();
|
||||||
|
|
||||||
let loc_when_pattern = &first.patterns[0];
|
let loc_when_pattern = &first.patterns[0];
|
||||||
|
|
||||||
let mono_pattern = from_can_pattern(env, procs, layout_cache, &loc_when_pattern.value);
|
let mono_pattern = from_can_pattern(env, procs, layout_cache, &loc_when_pattern.value);
|
||||||
|
@ -1247,11 +1266,16 @@ fn from_can_when<'a>(
|
||||||
|
|
||||||
// NOTE this will still store shadowed names.
|
// NOTE this will still store shadowed names.
|
||||||
// that's fine: the branch throws a runtime error anyway
|
// that's fine: the branch throws a runtime error anyway
|
||||||
let ret = match store_pattern(env, &mono_pattern, cond_symbol, cond_layout, &mut stored) {
|
let mut ret = match store_pattern(env, &mono_pattern, cond_symbol, cond_layout, &mut stored)
|
||||||
|
{
|
||||||
Ok(_) => from_can(env, first.value.value, procs, layout_cache),
|
Ok(_) => from_can(env, first.value.value, procs, layout_cache),
|
||||||
Err(message) => Expr::RuntimeError(env.arena.alloc(message)),
|
Err(message) => Expr::RuntimeError(env.arena.alloc(message)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for symbol in bound_symbols {
|
||||||
|
ret = Expr::DecAfter(symbol, env.arena.alloc(ret));
|
||||||
|
}
|
||||||
|
|
||||||
Expr::Store(stored.into_bump_slice(), arena.alloc(ret))
|
Expr::Store(stored.into_bump_slice(), arena.alloc(ret))
|
||||||
} else {
|
} else {
|
||||||
let cond_layout = layout_cache
|
let cond_layout = layout_cache
|
||||||
|
@ -1612,7 +1636,13 @@ fn specialize<'a>(
|
||||||
|
|
||||||
debug_assert!(matches!(unified, roc_unify::unify::Unified::Success(_)));
|
debug_assert!(matches!(unified, roc_unify::unify::Unified::Success(_)));
|
||||||
|
|
||||||
let specialized_body = from_can(env, body, procs, layout_cache);
|
let mut specialized_body = from_can(env, body, procs, layout_cache);
|
||||||
|
|
||||||
|
// TODO does order matter here?
|
||||||
|
for &symbol in pattern_symbols.iter() {
|
||||||
|
specialized_body = Expr::DecAfter(symbol, env.arena.alloc(specialized_body));
|
||||||
|
}
|
||||||
|
|
||||||
// reset subs, so we don't get type errors when specializing for a different signature
|
// reset subs, so we don't get type errors when specializing for a different signature
|
||||||
env.subs.rollback_to(snapshot);
|
env.subs.rollback_to(snapshot);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue