mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
WIP
This commit is contained in:
parent
cdec69d8a8
commit
9763f9b51b
7 changed files with 912 additions and 1 deletions
|
@ -605,6 +605,201 @@ fn call_spec(
|
|||
*update_mode,
|
||||
call.arguments,
|
||||
),
|
||||
NewHigherOrderLowLevel {
|
||||
specialization_id,
|
||||
closure_env_layout,
|
||||
op,
|
||||
arg_layouts,
|
||||
ret_layout,
|
||||
function_name,
|
||||
function_env,
|
||||
..
|
||||
} => {
|
||||
let array = specialization_id.to_bytes();
|
||||
let spec_var = CalleeSpecVar(&array);
|
||||
|
||||
let it = arg_layouts.iter().copied();
|
||||
let bytes = func_name_bytes_help(*function_name, it, *ret_layout);
|
||||
let name = FuncName(&bytes);
|
||||
let module = MOD_APP;
|
||||
|
||||
use crate::low_level::HigherOrder::*;
|
||||
|
||||
match op {
|
||||
DictWalk { xs, state } => {
|
||||
let dict = env.symbols[xs];
|
||||
let state = env.symbols[state];
|
||||
let closure_env = env.symbols[function_env];
|
||||
|
||||
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 first = builder.add_bag_get(block, bag)?;
|
||||
|
||||
let key = builder.add_get_tuple_field(block, first, 0)?;
|
||||
let val = builder.add_get_tuple_field(block, first, 1)?;
|
||||
|
||||
let argument = if closure_env_layout.is_none() {
|
||||
builder.add_make_tuple(block, &[state, key, val])?
|
||||
} else {
|
||||
builder.add_make_tuple(block, &[state, key, val, closure_env])?
|
||||
};
|
||||
builder.add_call(block, spec_var, module, name, argument)?;
|
||||
}
|
||||
|
||||
ListWalk { xs, state }
|
||||
| ListWalkBackwards { xs, state }
|
||||
| ListWalkUntil { xs, state } => {
|
||||
let list = env.symbols[xs];
|
||||
let state = env.symbols[state];
|
||||
let closure_env = env.symbols[function_env];
|
||||
|
||||
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 = if closure_env_layout.is_none() {
|
||||
builder.add_make_tuple(block, &[state, first])?
|
||||
} else {
|
||||
builder.add_make_tuple(block, &[state, first, closure_env])?
|
||||
};
|
||||
builder.add_call(block, spec_var, module, name, argument)?;
|
||||
}
|
||||
|
||||
ListMapWithIndex { xs } => {
|
||||
let list = env.symbols[xs];
|
||||
let closure_env = env.symbols[function_env];
|
||||
|
||||
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 = if closure_env_layout.is_none() {
|
||||
builder.add_make_tuple(block, &[index, first])?
|
||||
} else {
|
||||
builder.add_make_tuple(block, &[index, first, closure_env])?
|
||||
};
|
||||
builder.add_call(block, spec_var, module, name, argument)?;
|
||||
}
|
||||
|
||||
ListMap { xs } => {
|
||||
let list = env.symbols[xs];
|
||||
let closure_env = env.symbols[function_env];
|
||||
|
||||
let bag1 = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?;
|
||||
let _cell1 = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?;
|
||||
|
||||
let elem1 = builder.add_bag_get(block, bag1)?;
|
||||
|
||||
let argument = if closure_env_layout.is_none() {
|
||||
builder.add_make_tuple(block, &[elem1])?
|
||||
} else {
|
||||
builder.add_make_tuple(block, &[elem1, closure_env])?
|
||||
};
|
||||
builder.add_call(block, spec_var, module, name, argument)?;
|
||||
}
|
||||
|
||||
ListSortWith { xs } => {
|
||||
let list = env.symbols[xs];
|
||||
let closure_env = env.symbols[function_env];
|
||||
|
||||
let bag1 = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?;
|
||||
let _cell1 = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?;
|
||||
|
||||
let elem1 = builder.add_bag_get(block, bag1)?;
|
||||
|
||||
let argument = if closure_env_layout.is_none() {
|
||||
builder.add_make_tuple(block, &[elem1, elem1])?
|
||||
} else {
|
||||
builder.add_make_tuple(block, &[elem1, elem1, closure_env])?
|
||||
};
|
||||
builder.add_call(block, spec_var, module, name, argument)?;
|
||||
}
|
||||
|
||||
ListMap2 { xs, ys } => {
|
||||
let list1 = env.symbols[xs];
|
||||
let list2 = env.symbols[ys];
|
||||
let closure_env = env.symbols[function_env];
|
||||
|
||||
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 = if closure_env_layout.is_none() {
|
||||
builder.add_make_tuple(block, &[elem1, elem2])?
|
||||
} else {
|
||||
builder.add_make_tuple(block, &[elem1, elem2, closure_env])?
|
||||
};
|
||||
builder.add_call(block, spec_var, module, name, argument)?;
|
||||
}
|
||||
|
||||
ListMap3 { xs, ys, zs } => {
|
||||
let list1 = env.symbols[xs];
|
||||
let list2 = env.symbols[ys];
|
||||
let list3 = env.symbols[zs];
|
||||
let closure_env = env.symbols[function_env];
|
||||
|
||||
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 bag3 = builder.add_get_tuple_field(block, list3, LIST_BAG_INDEX)?;
|
||||
let _cell3 = builder.add_get_tuple_field(block, list3, LIST_CELL_INDEX)?;
|
||||
let elem3 = builder.add_bag_get(block, bag3)?;
|
||||
|
||||
let argument = if closure_env_layout.is_none() {
|
||||
builder.add_make_tuple(block, &[elem1, elem2, elem3])?
|
||||
} else {
|
||||
builder.add_make_tuple(block, &[elem1, elem2, elem3, closure_env])?
|
||||
};
|
||||
builder.add_call(block, spec_var, module, name, argument)?;
|
||||
}
|
||||
|
||||
ListKeepIf { xs } | ListKeepOks { xs } | ListKeepErrs { xs } => {
|
||||
let list = env.symbols[xs];
|
||||
let closure_env = env.symbols[function_env];
|
||||
|
||||
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 = if closure_env_layout.is_none() {
|
||||
builder.add_make_tuple(block, &[first])?
|
||||
} else {
|
||||
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)?;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO overly pessimstic
|
||||
// filter_map because one of the arguments is a function name, which
|
||||
// is not defined in the env
|
||||
let arguments: Vec<_> = call
|
||||
.arguments
|
||||
.iter()
|
||||
.filter_map(|symbol| env.symbols.get(symbol))
|
||||
.copied()
|
||||
.collect();
|
||||
|
||||
let result_type = layout_spec(builder, layout)?;
|
||||
|
||||
builder.add_unknown_with(block, &arguments, result_type)
|
||||
}
|
||||
HigherOrderLowLevel {
|
||||
specialization_id,
|
||||
closure_env_layout,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue