implement enough for Quicksort example

This commit is contained in:
Folkert 2021-05-08 23:41:55 +02:00
parent 4e57b3b0d7
commit fea8ab47cc
2 changed files with 33 additions and 8 deletions

View file

@ -2046,6 +2046,15 @@ fn update<'a>(
&& state.dependencies.solved_all() && state.dependencies.solved_all()
&& state.goal_phase == Phase::MakeSpecializations && state.goal_phase == Phase::MakeSpecializations
{ {
if false {
for proc in state.procedures.iter() {
println!("looking at {:?}", proc.1.name);
if let Err(e) = roc_mono::alias_analysis::proc_spec(&proc.1) {
println!("Error in {:?}: {:?}", proc.1.name, e)
}
}
}
Proc::insert_refcount_operations(arena, &mut state.procedures); Proc::insert_refcount_operations(arena, &mut state.procedures);
Proc::optimize_refcount_operations( Proc::optimize_refcount_operations(

View file

@ -21,8 +21,8 @@ pub fn proc_spec(proc: &Proc) -> Result<FuncDef> {
let block = builder.add_block(); let block = builder.add_block();
// introduce the arguments
let mut argument_layouts = Vec::new(); let mut argument_layouts = Vec::new();
for (i, (layout, symbol)) in proc.args.iter().enumerate() { for (i, (layout, symbol)) in proc.args.iter().enumerate() {
let value_id = builder.add_get_tuple_field(block, morphic_lib::ARG_VALUE_ID, i as u32)?; let value_id = builder.add_get_tuple_field(block, morphic_lib::ARG_VALUE_ID, i as u32)?;
env.symbols.insert(*symbol, value_id); env.symbols.insert(*symbol, value_id);
@ -143,9 +143,8 @@ fn stmt_spec(
let jp_body_value_id = stmt_spec(builder, env, jp_body_block, layout, remainder)?; let jp_body_value_id = stmt_spec(builder, env, jp_body_block, layout, remainder)?;
for p in parameters.iter() { // NOTE the symbols bound by the join point can shadow the argument symbols of the
env.symbols.remove(&p.symbol); // surrounding function, so we don't remove them from the env here
}
// NOTE I think we need to use add_sub_block here, but not sure how // NOTE I think we need to use add_sub_block here, but not sure how
@ -181,7 +180,13 @@ fn build_tuple_value(
let mut value_ids = Vec::new(); let mut value_ids = Vec::new();
for field in symbols.iter() { for field in symbols.iter() {
let value_id = env.symbols[field]; let value_id = match env.symbols.get(field) {
None => panic!(
"Symbol {:?} is not defined in environment {:?}",
field, &env.symbols
),
Some(x) => *x,
};
value_ids.push(value_id); value_ids.push(value_id);
} }
@ -254,7 +259,7 @@ fn lowlevel_spec(
match op { match op {
NumAdd | NumSub => { NumAdd | NumSub => {
// NOTE some numeric operations panic (e.g. on overflow) // NOTE these numeric operations panic (e.g. on overflow)
let pass_block = { let pass_block = {
let block = builder.add_block(); let block = builder.add_block();
@ -277,6 +282,7 @@ fn lowlevel_spec(
builder.add_sub_block(block, sub_block) builder.add_sub_block(block, sub_block)
} }
Eq | NotEq => new_bool(builder, block),
NumLte | NumLt | NumGt | NumGte => new_order(builder, block), NumLte | NumLt | NumGt | NumGte => new_order(builder, block),
ListLen => { ListLen => {
let list = env.symbols[&arguments[0]]; let list = env.symbols[&arguments[0]];
@ -309,7 +315,7 @@ fn lowlevel_spec(
Ok(list) Ok(list)
} }
_ => todo!(), other => todo!("lowlevel op not implemented: {:?}", other),
} }
} }
@ -399,7 +405,8 @@ fn expr_spec(
builder.add_get_tuple_field(block, value_id, *index as u32) builder.add_get_tuple_field(block, value_id, *index as u32)
} }
Wrapped::MultiTagUnion => { Wrapped::MultiTagUnion => {
todo!("the complicated case") // TODO this is likely wrong; how can we extract a field from an union constructor?
builder.add_get_tuple_field(block, value_id, *index as u32)
} }
} }
} }
@ -537,6 +544,15 @@ fn new_order(builder: &mut FuncDefBuilder, block: BlockId) -> Result<ValueId> {
builder.add_make_union(block, &[unit, unit, unit], tag_id, unit_value) builder.add_make_union(block, &[unit, unit, unit], tag_id, unit_value)
} }
fn new_bool(builder: &mut FuncDefBuilder, block: BlockId) -> Result<ValueId> {
// always generats False
let tag_id = 0;
let unit = builder.add_tuple_type(&[])?;
let unit_value = builder.add_make_tuple(block, &[])?;
builder.add_make_union(block, &[unit, unit], tag_id, unit_value)
}
fn new_num(builder: &mut FuncDefBuilder, block: BlockId) -> Result<ValueId> { fn new_num(builder: &mut FuncDefBuilder, block: BlockId) -> Result<ValueId> {
// we model all our numbers as unit values // we model all our numbers as unit values
builder.add_make_tuple(block, &[]) builder.add_make_tuple(block, &[])