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);
|
||||
}
|
||||
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,
|
||||
|
||||
/// RC instructions
|
||||
IncBefore(Symbol, &'a Expr<'a>),
|
||||
DecAfter(Symbol, &'a Expr<'a>),
|
||||
|
||||
RuntimeError(&'a str),
|
||||
}
|
||||
|
||||
|
@ -600,12 +604,20 @@ fn from_can<'a>(
|
|||
layout_cache,
|
||||
)
|
||||
} 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),
|
||||
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) => {
|
||||
|
@ -1208,6 +1220,13 @@ fn from_can_when<'a>(
|
|||
let arena = env.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 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.
|
||||
// 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),
|
||||
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))
|
||||
} else {
|
||||
let cond_layout = layout_cache
|
||||
|
@ -1612,7 +1636,13 @@ fn specialize<'a>(
|
|||
|
||||
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
|
||||
env.subs.rollback_to(snapshot);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue