mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 00:01:16 +00:00
generate IR that uses uniqueness
This commit is contained in:
parent
8803cb9523
commit
84a8b69437
11 changed files with 301 additions and 98 deletions
|
@ -1087,7 +1087,34 @@ pub fn with_hole<'a>(
|
|||
),
|
||||
},
|
||||
LetNonRec(def, cont, _, _) => {
|
||||
// WRONG! this is introduces new control flow, and should call `from_can` again
|
||||
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
||||
if let Closure(_, _, _, _, _) = &def.loc_expr.value {
|
||||
// Now that we know for sure it's a closure, get an owned
|
||||
// version of these variant args so we can use them properly.
|
||||
match def.loc_expr.value {
|
||||
Closure(ann, _, _, loc_args, boxed_body) => {
|
||||
// Extract Procs, but discard the resulting Expr::Load.
|
||||
// That Load looks up the pointer, which we won't use here!
|
||||
|
||||
let (loc_body, ret_var) = *boxed_body;
|
||||
|
||||
procs.insert_named(
|
||||
env,
|
||||
layout_cache,
|
||||
*symbol,
|
||||
ann,
|
||||
loc_args,
|
||||
loc_body,
|
||||
ret_var,
|
||||
);
|
||||
|
||||
return with_hole(env, cont.value, procs, layout_cache, assigned, hole);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let roc_can::pattern::Pattern::Identifier(symbol) = def.loc_pattern.value {
|
||||
let mut stmt = with_hole(env, cont.value, procs, layout_cache, assigned, hole);
|
||||
|
||||
|
@ -1108,50 +1135,75 @@ pub fn with_hole<'a>(
|
|||
// this may be a destructure pattern
|
||||
let mono_pattern = from_can_pattern(env, layout_cache, &def.loc_pattern.value);
|
||||
|
||||
if let Pattern::Identifier(symbol) = mono_pattern {
|
||||
let hole = env
|
||||
.arena
|
||||
.alloc(from_can(env, cont.value, procs, layout_cache));
|
||||
with_hole(env, def.loc_expr.value, procs, layout_cache, symbol, hole)
|
||||
} else {
|
||||
let context = crate::exhaustive::Context::BadDestruct;
|
||||
match crate::exhaustive::check(
|
||||
def.loc_pattern.region,
|
||||
&[(
|
||||
Located::at(def.loc_pattern.region, mono_pattern.clone()),
|
||||
crate::exhaustive::Guard::NoGuard,
|
||||
)],
|
||||
context,
|
||||
) {
|
||||
Ok(_) => {}
|
||||
Err(errors) => {
|
||||
for error in errors {
|
||||
env.problems.push(MonoProblem::PatternProblem(error))
|
||||
}
|
||||
} // TODO make all variables bound in the pattern evaluate to a runtime error
|
||||
// return Stmt::RuntimeError("TODO non-exhaustive pattern");
|
||||
}
|
||||
|
||||
// convert the continuation
|
||||
let mut stmt = from_can(env, cont.value, procs, layout_cache);
|
||||
|
||||
let outer_symbol = env.unique_symbol();
|
||||
stmt =
|
||||
store_pattern(env, procs, layout_cache, &mono_pattern, outer_symbol, stmt)
|
||||
.unwrap();
|
||||
|
||||
// convert the def body, store in outer_symbol
|
||||
with_hole(
|
||||
env,
|
||||
def.loc_expr.value,
|
||||
procs,
|
||||
layout_cache,
|
||||
outer_symbol,
|
||||
env.arena.alloc(stmt),
|
||||
)
|
||||
let context = crate::exhaustive::Context::BadDestruct;
|
||||
match crate::exhaustive::check(
|
||||
def.loc_pattern.region,
|
||||
&[(
|
||||
Located::at(def.loc_pattern.region, mono_pattern.clone()),
|
||||
crate::exhaustive::Guard::NoGuard,
|
||||
)],
|
||||
context,
|
||||
) {
|
||||
Ok(_) => {}
|
||||
Err(errors) => {
|
||||
for error in errors {
|
||||
env.problems.push(MonoProblem::PatternProblem(error))
|
||||
}
|
||||
} // TODO make all variables bound in the pattern evaluate to a runtime error
|
||||
// return Stmt::RuntimeError("TODO non-exhaustive pattern");
|
||||
}
|
||||
|
||||
// convert the continuation
|
||||
let mut stmt = with_hole(env, cont.value, procs, layout_cache, assigned, hole);
|
||||
|
||||
let outer_symbol = env.unique_symbol();
|
||||
stmt = store_pattern(env, procs, layout_cache, &mono_pattern, outer_symbol, stmt)
|
||||
.unwrap();
|
||||
|
||||
// convert the def body, store in outer_symbol
|
||||
with_hole(
|
||||
env,
|
||||
def.loc_expr.value,
|
||||
procs,
|
||||
layout_cache,
|
||||
outer_symbol,
|
||||
env.arena.alloc(stmt),
|
||||
)
|
||||
}
|
||||
}
|
||||
LetRec(defs, cont, _, _) => {
|
||||
// because Roc is strict, only functions can be recursive!
|
||||
for def in defs.into_iter() {
|
||||
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
||||
// Now that we know for sure it's a closure, get an owned
|
||||
// version of these variant args so we can use them properly.
|
||||
match def.loc_expr.value {
|
||||
Closure(ann, _, _, loc_args, boxed_body) => {
|
||||
// Extract Procs, but discard the resulting Expr::Load.
|
||||
// That Load looks up the pointer, which we won't use here!
|
||||
|
||||
let (loc_body, ret_var) = *boxed_body;
|
||||
|
||||
procs.insert_named(
|
||||
env,
|
||||
layout_cache,
|
||||
*symbol,
|
||||
ann,
|
||||
loc_args,
|
||||
loc_body,
|
||||
ret_var,
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
_ => unreachable!("recursive value is not a function"),
|
||||
}
|
||||
}
|
||||
unreachable!("recursive value does not have Identifier pattern")
|
||||
}
|
||||
|
||||
with_hole(env, cont.value, procs, layout_cache, assigned, hole)
|
||||
}
|
||||
Var(symbol) => {
|
||||
if procs.module_thunks.contains(&symbol) {
|
||||
let partial_proc = procs.partial_procs.get(&symbol).unwrap();
|
||||
|
@ -1578,7 +1630,6 @@ pub fn with_hole<'a>(
|
|||
|
||||
stmt
|
||||
}
|
||||
LetRec(_, _, _, _) => todo!("lets"),
|
||||
|
||||
Access {
|
||||
record_var,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue