mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
fix things in alias analysis
This commit is contained in:
parent
b622202d97
commit
0e6e9847fc
1 changed files with 97 additions and 15 deletions
|
@ -114,8 +114,15 @@ where
|
||||||
m.add_const(STATIC_STR_NAME, static_str_def)?;
|
m.add_const(STATIC_STR_NAME, static_str_def)?;
|
||||||
|
|
||||||
// the entry point wrapper
|
// the entry point wrapper
|
||||||
|
let roc_main_bytes = func_name_bytes_help(
|
||||||
|
entry_point.symbol,
|
||||||
|
entry_point.layout.arguments.iter().copied(),
|
||||||
|
entry_point.layout.result,
|
||||||
|
);
|
||||||
|
let roc_main = FuncName(&roc_main_bytes);
|
||||||
|
|
||||||
|
let entry_point_function = build_entry_point(entry_point.layout, roc_main)?;
|
||||||
let entry_point_name = FuncName(ENTRY_POINT_NAME);
|
let entry_point_name = FuncName(ENTRY_POINT_NAME);
|
||||||
let entry_point_function = build_entry_point(entry_point.layout, entry_point_name)?;
|
|
||||||
m.add_func(entry_point_name, entry_point_function)?;
|
m.add_func(entry_point_name, entry_point_function)?;
|
||||||
|
|
||||||
// all other functions
|
// all other functions
|
||||||
|
@ -124,7 +131,12 @@ where
|
||||||
|
|
||||||
let bytes = func_name_bytes(proc);
|
let bytes = func_name_bytes(proc);
|
||||||
let func_name = FuncName(&bytes);
|
let func_name = FuncName(&bytes);
|
||||||
eprintln!("{:?}: {:?}", proc.name, bytes_as_ascii(&bytes));
|
eprintln!(
|
||||||
|
"{:?}: {:?} with {:?} args",
|
||||||
|
proc.name,
|
||||||
|
bytes_as_ascii(&bytes),
|
||||||
|
proc.args.len()
|
||||||
|
);
|
||||||
|
|
||||||
m.add_func(func_name, spec)?;
|
m.add_func(func_name, spec)?;
|
||||||
}
|
}
|
||||||
|
@ -298,7 +310,7 @@ fn stmt_spec(
|
||||||
Join {
|
Join {
|
||||||
id,
|
id,
|
||||||
parameters,
|
parameters,
|
||||||
body: continuation,
|
body,
|
||||||
remainder,
|
remainder,
|
||||||
} => {
|
} => {
|
||||||
let mut type_ids = Vec::new();
|
let mut type_ids = Vec::new();
|
||||||
|
@ -314,27 +326,33 @@ fn stmt_spec(
|
||||||
let (jpid, jp_argument) =
|
let (jpid, jp_argument) =
|
||||||
builder.declare_continuation(block, jp_arg_type_id, ret_type_id)?;
|
builder.declare_continuation(block, jp_arg_type_id, ret_type_id)?;
|
||||||
|
|
||||||
|
// NOTE join point arguments can shadow variables from the outer scope
|
||||||
|
// the ordering of steps here is important
|
||||||
|
|
||||||
|
// add this ID so both body and remainder can reference it
|
||||||
|
env.join_points.insert(*id, jpid);
|
||||||
|
|
||||||
|
// first, with the current variable bindings, process the remainder
|
||||||
|
let cont_block = builder.add_block();
|
||||||
|
let cont_value_id = stmt_spec(builder, env, cont_block, layout, remainder)?;
|
||||||
|
|
||||||
|
// only then introduce variables bound by the jump point, and process its body
|
||||||
let join_body_sub_block = {
|
let join_body_sub_block = {
|
||||||
env.join_points.insert(*id, jpid);
|
|
||||||
let jp_body_block = builder.add_block();
|
let jp_body_block = builder.add_block();
|
||||||
|
|
||||||
// unpack the argument
|
// unpack the argument
|
||||||
for (i, p) in parameters.iter().enumerate() {
|
for (i, p) in parameters.iter().enumerate() {
|
||||||
let value_id =
|
let value_id =
|
||||||
builder.add_get_tuple_field(jp_body_block, jp_argument, i as u32)?;
|
builder.add_get_tuple_field(jp_body_block, jp_argument, i as u32)?;
|
||||||
|
|
||||||
env.symbols.insert(p.symbol, value_id);
|
env.symbols.insert(p.symbol, value_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
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, body)?;
|
||||||
|
|
||||||
BlockExpr(jp_body_block, jp_body_value_id)
|
BlockExpr(jp_body_block, jp_body_value_id)
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE the symbols bound by the join point can shadow the argument symbols of the
|
|
||||||
// surrounding function, so we don't remove them from the env here
|
|
||||||
|
|
||||||
let cont_block = builder.add_block();
|
|
||||||
let cont_value_id = stmt_spec(builder, env, cont_block, layout, continuation)?;
|
|
||||||
|
|
||||||
env.join_points.remove(id);
|
env.join_points.remove(id);
|
||||||
builder.define_continuation(jpid, join_body_sub_block)?;
|
builder.define_continuation(jpid, join_body_sub_block)?;
|
||||||
|
|
||||||
|
@ -474,15 +492,77 @@ fn call_spec(
|
||||||
DictWalk => {
|
DictWalk => {
|
||||||
let dict = env.symbols[&call.arguments[0]];
|
let dict = env.symbols[&call.arguments[0]];
|
||||||
let default = env.symbols[&call.arguments[1]];
|
let default = env.symbols[&call.arguments[1]];
|
||||||
|
let closure_env = env.symbols[&call.arguments[3]];
|
||||||
|
|
||||||
let bag = builder.add_get_tuple_field(block, dict, DICT_BAG_INDEX)?;
|
let bag = builder.add_get_tuple_field(block, dict, DICT_BAG_INDEX)?;
|
||||||
let _cell = builder.add_get_tuple_field(block, dict, DICT_CELL_INDEX)?;
|
let _cell = builder.add_get_tuple_field(block, dict, DICT_CELL_INDEX)?;
|
||||||
|
|
||||||
let first = builder.add_bag_get(block, bag)?;
|
let first = builder.add_bag_get(block, bag)?;
|
||||||
|
|
||||||
let argument = builder.add_make_tuple(block, &[first, default])?;
|
let key = builder.add_get_tuple_field(block, first, 0)?;
|
||||||
|
let val = builder.add_get_tuple_field(block, first, 1)?;
|
||||||
|
|
||||||
|
let argument =
|
||||||
|
builder.add_make_tuple(block, &[key, val, default, closure_env])?;
|
||||||
builder.add_call(block, spec_var, module, name, argument)?;
|
builder.add_call(block, spec_var, module, name, argument)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ListMapWithIndex => {
|
||||||
|
let list = env.symbols[&call.arguments[0]];
|
||||||
|
|
||||||
|
let bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?;
|
||||||
|
let _cell = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?;
|
||||||
|
|
||||||
|
let first = builder.add_bag_get(block, bag)?;
|
||||||
|
let index = builder.add_make_tuple(block, &[])?;
|
||||||
|
|
||||||
|
let argument = builder.add_make_tuple(block, &[first, index])?;
|
||||||
|
builder.add_call(block, spec_var, module, name, argument)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListMap => {
|
||||||
|
let list1 = env.symbols[&call.arguments[0]];
|
||||||
|
|
||||||
|
let bag1 = builder.add_get_tuple_field(block, list1, LIST_BAG_INDEX)?;
|
||||||
|
let _cell1 = builder.add_get_tuple_field(block, list1, LIST_CELL_INDEX)?;
|
||||||
|
|
||||||
|
let elem1 = builder.add_bag_get(block, bag1)?;
|
||||||
|
|
||||||
|
let argument = builder.add_make_tuple(block, &[elem1])?;
|
||||||
|
builder.add_call(block, spec_var, module, name, argument)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListMap2 => {
|
||||||
|
let list1 = env.symbols[&call.arguments[0]];
|
||||||
|
let list2 = env.symbols[&call.arguments[1]];
|
||||||
|
|
||||||
|
let bag1 = builder.add_get_tuple_field(block, list1, LIST_BAG_INDEX)?;
|
||||||
|
let _cell1 = builder.add_get_tuple_field(block, list1, LIST_CELL_INDEX)?;
|
||||||
|
let elem1 = builder.add_bag_get(block, bag1)?;
|
||||||
|
|
||||||
|
let bag2 = builder.add_get_tuple_field(block, list2, LIST_BAG_INDEX)?;
|
||||||
|
let _cell2 = builder.add_get_tuple_field(block, list2, LIST_CELL_INDEX)?;
|
||||||
|
let elem2 = builder.add_bag_get(block, bag2)?;
|
||||||
|
|
||||||
|
let argument = builder.add_make_tuple(block, &[elem1, elem2])?;
|
||||||
|
builder.add_call(block, spec_var, module, name, argument)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListKeepIf | ListKeepOks | ListKeepErrs => {
|
||||||
|
let list = env.symbols[&call.arguments[0]];
|
||||||
|
let closure_env = env.symbols[&call.arguments[2]];
|
||||||
|
|
||||||
|
let bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?;
|
||||||
|
// let _cell = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?;
|
||||||
|
|
||||||
|
let first = builder.add_bag_get(block, bag)?;
|
||||||
|
|
||||||
|
let argument = builder.add_make_tuple(block, &[first, closure_env])?;
|
||||||
|
let result = builder.add_call(block, spec_var, module, name, argument)?;
|
||||||
|
let unit = builder.add_tuple_type(&[])?;
|
||||||
|
builder.add_unknown_with(block, &[result], unit)?;
|
||||||
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
// fake a call to the function argument
|
// fake a call to the function argument
|
||||||
// to make sure the function is specialized
|
// to make sure the function is specialized
|
||||||
|
@ -698,7 +778,10 @@ fn expr_spec(
|
||||||
let result_type = layout_spec(builder, layout)?;
|
let result_type = layout_spec(builder, layout)?;
|
||||||
builder.add_unknown_with(block, &[value_id], result_type)
|
builder.add_unknown_with(block, &[value_id], result_type)
|
||||||
} else {
|
} else {
|
||||||
builder.add_get_tuple_field(block, value_id, *index as u32)
|
// what to do, what to do.
|
||||||
|
let result_type = layout_spec(builder, layout)?;
|
||||||
|
builder.add_unknown_with(block, &[value_id], result_type)
|
||||||
|
// builder.add_get_tuple_field(block, value_id, *index as u32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -843,8 +926,7 @@ fn builtin_spec(builder: &mut FuncDefBuilder, builtin: &Builtin) -> Result<TypeI
|
||||||
|
|
||||||
fn str_type<TC: TypeContext>(builder: &mut TC) -> Result<TypeId> {
|
fn str_type<TC: TypeContext>(builder: &mut TC) -> Result<TypeId> {
|
||||||
let cell_id = builder.add_heap_cell_type();
|
let cell_id = builder.add_heap_cell_type();
|
||||||
let len_id = builder.add_tuple_type(&[])?;
|
builder.add_tuple_type(&[cell_id])
|
||||||
builder.add_tuple_type(&[cell_id, len_id])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// const OK_TAG_ID: u8 = 1u8;
|
// const OK_TAG_ID: u8 = 1u8;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue