mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 00:09:33 +03:00
make patterns store their bound variables
This commit is contained in:
parent
6310341b7e
commit
c3d550116b
@ -136,7 +136,6 @@ mod test_gen {
|
|||||||
// TODO try deleting this line and seeing if everything still works.
|
// TODO try deleting this line and seeing if everything still works.
|
||||||
builder.append_block_params_for_function_params(block);
|
builder.append_block_params_for_function_params(block);
|
||||||
|
|
||||||
dbg!(&mono_expr);
|
|
||||||
let main_body =
|
let main_body =
|
||||||
roc_gen::crane::build::build_expr(&env, &scope, &mut module, &mut builder, &mono_expr, &procs);
|
roc_gen::crane::build::build_expr(&env, &scope, &mut module, &mut builder, &mono_expr, &procs);
|
||||||
|
|
||||||
@ -677,20 +676,20 @@ mod test_gen {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn branch_store_variable() {
|
fn branch_store_variable() {
|
||||||
// assert_evals_to!(
|
assert_evals_to!(
|
||||||
// indoc!(
|
indoc!(
|
||||||
// r#"
|
r#"
|
||||||
// when 0 is
|
when 0 is
|
||||||
// 1 -> 12
|
1 -> 12
|
||||||
// a -> a
|
a -> a
|
||||||
// "#
|
"#
|
||||||
// ),
|
),
|
||||||
// 0,
|
0,
|
||||||
// i64
|
i64
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn gen_when_one_branch() {
|
fn gen_when_one_branch() {
|
||||||
|
@ -426,7 +426,7 @@ fn from_can<'a>(
|
|||||||
store_pattern(
|
store_pattern(
|
||||||
env,
|
env,
|
||||||
mono_pattern,
|
mono_pattern,
|
||||||
loc_expr.value,
|
&loc_expr.value,
|
||||||
def.expr_var,
|
def.expr_var,
|
||||||
procs,
|
procs,
|
||||||
&mut stored,
|
&mut stored,
|
||||||
@ -807,7 +807,7 @@ fn from_can<'a>(
|
|||||||
fn store_pattern<'a>(
|
fn store_pattern<'a>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
can_pat: Pattern,
|
can_pat: Pattern,
|
||||||
can_expr: roc_can::expr::Expr,
|
can_expr: &roc_can::expr::Expr,
|
||||||
var: Variable,
|
var: Variable,
|
||||||
procs: &mut Procs<'a>,
|
procs: &mut Procs<'a>,
|
||||||
stored: &mut Vec<'a, (Symbol, Layout<'a>, Expr<'a>)>,
|
stored: &mut Vec<'a, (Symbol, Layout<'a>, Expr<'a>)>,
|
||||||
@ -835,13 +835,15 @@ fn store_pattern<'a>(
|
|||||||
// identity 5
|
// identity 5
|
||||||
//
|
//
|
||||||
match can_pat {
|
match can_pat {
|
||||||
Identifier(symbol) => stored.push((symbol, layout, from_can(env, can_expr, procs, None))),
|
Identifier(symbol) => {
|
||||||
|
stored.push((symbol, layout, from_can(env, can_expr.clone(), procs, None)))
|
||||||
|
}
|
||||||
Underscore => {
|
Underscore => {
|
||||||
// Since _ is never read, it's safe to reassign it.
|
// Since _ is never read, it's safe to reassign it.
|
||||||
stored.push((
|
stored.push((
|
||||||
Symbol::UNDERSCORE,
|
Symbol::UNDERSCORE,
|
||||||
layout,
|
layout,
|
||||||
from_can(env, can_expr, procs, None),
|
from_can(env, can_expr.clone(), procs, None),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@ -850,6 +852,44 @@ fn store_pattern<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn store_pattern2<'a>(
|
||||||
|
env: &mut Env<'a, '_>,
|
||||||
|
can_pat: &Pattern,
|
||||||
|
outer_symbol: Symbol,
|
||||||
|
_index: u64,
|
||||||
|
var: Variable,
|
||||||
|
stored: &mut Vec<'a, (Symbol, Layout<'a>, Expr<'a>)>,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
use Pattern::*;
|
||||||
|
|
||||||
|
let layout = match Layout::from_var(env.arena, var, env.subs, env.pointer_size) {
|
||||||
|
Ok(layout) => layout,
|
||||||
|
Err(()) => {
|
||||||
|
panic!("TODO gen a runtime error here");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match can_pat {
|
||||||
|
Identifier(symbol) => stored.push((*symbol, layout, Expr::Load(outer_symbol))),
|
||||||
|
Underscore => {
|
||||||
|
// Since _ is never read, it's safe to reassign it.
|
||||||
|
stored.push((Symbol::UNDERSCORE, layout, Expr::Load(outer_symbol)))
|
||||||
|
}
|
||||||
|
IntLiteral(_) | FloatLiteral(_) | EnumLiteral { .. } | BitLiteral(_) => {}
|
||||||
|
Shadowed(region, ident) => {
|
||||||
|
return Err(format!(
|
||||||
|
"The pattern at {:?} shadows variable {:?}",
|
||||||
|
region, ident
|
||||||
|
));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("TODO store_pattern for {:?}", can_pat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn from_can_when<'a>(
|
fn from_can_when<'a>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
cond_var: Variable,
|
cond_var: Variable,
|
||||||
@ -878,7 +918,7 @@ fn from_can_when<'a>(
|
|||||||
store_pattern(
|
store_pattern(
|
||||||
env,
|
env,
|
||||||
mono_pattern,
|
mono_pattern,
|
||||||
loc_cond.value,
|
&loc_cond.value,
|
||||||
cond_var,
|
cond_var,
|
||||||
procs,
|
procs,
|
||||||
&mut stored,
|
&mut stored,
|
||||||
@ -889,6 +929,12 @@ fn from_can_when<'a>(
|
|||||||
Expr::Store(stored.into_bump_slice(), arena.alloc(ret))
|
Expr::Store(stored.into_bump_slice(), arena.alloc(ret))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
let cond_layout = Layout::from_var(env.arena, cond_var, env.subs, env.pointer_size)
|
||||||
|
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
|
let cond = from_can(env, loc_cond.value, procs, None);
|
||||||
|
let cond_symbol = env.fresh_symbol();
|
||||||
|
|
||||||
let mut loc_branches = std::vec::Vec::new();
|
let mut loc_branches = std::vec::Vec::new();
|
||||||
let mut opt_branches = std::vec::Vec::new();
|
let mut opt_branches = std::vec::Vec::new();
|
||||||
|
|
||||||
@ -897,7 +943,17 @@ fn from_can_when<'a>(
|
|||||||
|
|
||||||
loc_branches.push(Located::at(loc_pattern.region, mono_pattern.clone()));
|
loc_branches.push(Located::at(loc_pattern.region, mono_pattern.clone()));
|
||||||
|
|
||||||
let mono_expr = from_can(env, loc_expr.value, procs, None);
|
let mut stores = Vec::with_capacity_in(1, env.arena);
|
||||||
|
|
||||||
|
let mono_expr =
|
||||||
|
match store_pattern2(env, &mono_pattern, cond_symbol, 0, cond_var, &mut stores)
|
||||||
|
{
|
||||||
|
Ok(_) => Expr::Store(
|
||||||
|
stores.into_bump_slice(),
|
||||||
|
env.arena.alloc(from_can(env, loc_expr.value, procs, None)),
|
||||||
|
),
|
||||||
|
Err(message) => Expr::RuntimeError(env.arena.alloc(message)),
|
||||||
|
};
|
||||||
|
|
||||||
opt_branches.push((mono_pattern, mono_expr));
|
opt_branches.push((mono_pattern, mono_expr));
|
||||||
}
|
}
|
||||||
@ -907,13 +963,6 @@ fn from_can_when<'a>(
|
|||||||
Err(errors) => panic!("Errors in patterns: {:?}", errors),
|
Err(errors) => panic!("Errors in patterns: {:?}", errors),
|
||||||
}
|
}
|
||||||
|
|
||||||
let cond = from_can(env, loc_cond.value, procs, None);
|
|
||||||
let cond_symbol = env.fresh_symbol();
|
|
||||||
|
|
||||||
// TODO store cond in the symbol
|
|
||||||
let cond_layout = Layout::from_var(env.arena, cond_var, env.subs, env.pointer_size)
|
|
||||||
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
|
||||||
|
|
||||||
let ret_layout = Layout::from_var(env.arena, expr_var, env.subs, env.pointer_size)
|
let ret_layout = Layout::from_var(env.arena, expr_var, env.subs, env.pointer_size)
|
||||||
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO turn this into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user