mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
work on higher order lowlevels
This commit is contained in:
parent
9476f63e07
commit
86f35c33cd
6 changed files with 81 additions and 14 deletions
|
@ -826,6 +826,7 @@ pub fn build_exp_call<'a, 'ctx, 'env>(
|
||||||
closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
specialization_id,
|
specialization_id,
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
let bytes = specialization_id.to_bytes();
|
let bytes = specialization_id.to_bytes();
|
||||||
let callee_var = CalleeSpecVar(&bytes);
|
let callee_var = CalleeSpecVar(&bytes);
|
||||||
|
@ -3815,18 +3816,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
($index:expr) => {{
|
($index:expr) => {{
|
||||||
let function_symbol = args[$index];
|
let function_symbol = args[$index];
|
||||||
|
|
||||||
let fn_name = layout_ids
|
function_value_by_func_spec(env, func_spec, function_symbol, function_layout)
|
||||||
.get(function_symbol, &function_layout)
|
|
||||||
.to_symbol_string(function_symbol, &env.interns);
|
|
||||||
|
|
||||||
env.module
|
|
||||||
.get_function(fn_name.as_str())
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
panic!(
|
|
||||||
"Could not get pointer to unknown function {:?} {:?}",
|
|
||||||
fn_name, function_layout
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -414,7 +414,64 @@ fn call_spec(
|
||||||
*update_mode,
|
*update_mode,
|
||||||
call.arguments,
|
call.arguments,
|
||||||
),
|
),
|
||||||
HigherOrderLowLevel { op, .. } => {
|
HigherOrderLowLevel {
|
||||||
|
specialization_id,
|
||||||
|
closure_layout: _,
|
||||||
|
op,
|
||||||
|
arg_layouts,
|
||||||
|
ret_layout,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let array = specialization_id.to_bytes();
|
||||||
|
let spec_var = CalleeSpecVar(&array);
|
||||||
|
|
||||||
|
let symbol = {
|
||||||
|
use roc_module::low_level::LowLevel::*;
|
||||||
|
|
||||||
|
match op {
|
||||||
|
ListMap | ListMapWithIndex => call.arguments[1],
|
||||||
|
ListMap2 => call.arguments[2],
|
||||||
|
ListMap3 => call.arguments[3],
|
||||||
|
ListWalk | ListWalkUntil | ListWalkBackwards | DictWalk => call.arguments[2],
|
||||||
|
ListKeepIf | ListKeepOks | ListKeepErrs => call.arguments[1],
|
||||||
|
ListSortWith => call.arguments[1],
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let it = arg_layouts.iter().copied();
|
||||||
|
let bytes = func_name_bytes_help(symbol, it, *ret_layout);
|
||||||
|
let name = FuncName(&bytes);
|
||||||
|
let module = MOD_APP;
|
||||||
|
|
||||||
|
{
|
||||||
|
use roc_module::low_level::LowLevel::*;
|
||||||
|
|
||||||
|
match op {
|
||||||
|
DictWalk => {
|
||||||
|
let dict = env.symbols[&call.arguments[0]];
|
||||||
|
let default = env.symbols[&call.arguments[1]];
|
||||||
|
|
||||||
|
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 argument = builder.add_make_tuple(block, &[first, default])?;
|
||||||
|
builder.add_call(block, spec_var, module, name, argument)?;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// fake a call to the function argument
|
||||||
|
// to make sure the function is specialized
|
||||||
|
|
||||||
|
// very invalid
|
||||||
|
let arg_value_id = build_tuple_value(builder, env, block, &[])?;
|
||||||
|
|
||||||
|
builder.add_call(block, spec_var, module, name, arg_value_id)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO overly pessimstic
|
// TODO overly pessimstic
|
||||||
// filter_map because one of the arguments is a function name, which
|
// filter_map because one of the arguments is a function name, which
|
||||||
// is not defined in the env
|
// is not defined in the env
|
||||||
|
@ -773,6 +830,9 @@ fn str_type<TC: TypeContext>(builder: &mut TC) -> Result<TypeId> {
|
||||||
const LIST_CELL_INDEX: u32 = 0;
|
const LIST_CELL_INDEX: u32 = 0;
|
||||||
const LIST_BAG_INDEX: u32 = 1;
|
const LIST_BAG_INDEX: u32 = 1;
|
||||||
|
|
||||||
|
const DICT_CELL_INDEX: u32 = LIST_CELL_INDEX;
|
||||||
|
const DICT_BAG_INDEX: u32 = LIST_BAG_INDEX;
|
||||||
|
|
||||||
fn new_list(builder: &mut FuncDefBuilder, block: BlockId, element_type: TypeId) -> Result<ValueId> {
|
fn new_list(builder: &mut FuncDefBuilder, block: BlockId, element_type: TypeId) -> Result<ValueId> {
|
||||||
let cell = builder.add_new_heap_cell(block)?;
|
let cell = builder.add_new_heap_cell(block)?;
|
||||||
let bag = builder.add_empty_bag(block, element_type)?;
|
let bag = builder.add_empty_bag(block, element_type)?;
|
||||||
|
|
|
@ -457,6 +457,8 @@ impl<'a> Context<'a> {
|
||||||
op,
|
op,
|
||||||
closure_layout,
|
closure_layout,
|
||||||
specialization_id,
|
specialization_id,
|
||||||
|
arg_layouts,
|
||||||
|
ret_layout,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
macro_rules! create_call {
|
macro_rules! create_call {
|
||||||
|
@ -468,6 +470,8 @@ impl<'a> Context<'a> {
|
||||||
closure_layout: *closure_layout,
|
closure_layout: *closure_layout,
|
||||||
function_owns_closure_data: true,
|
function_owns_closure_data: true,
|
||||||
specialization_id: *specialization_id,
|
specialization_id: *specialization_id,
|
||||||
|
arg_layouts,
|
||||||
|
ret_layout: *ret_layout,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
call_type
|
call_type
|
||||||
|
|
|
@ -1150,6 +1150,9 @@ pub enum CallType<'a> {
|
||||||
specialization_id: CallSpecId,
|
specialization_id: CallSpecId,
|
||||||
/// does the function need to own the closure data
|
/// does the function need to own the closure data
|
||||||
function_owns_closure_data: bool,
|
function_owns_closure_data: bool,
|
||||||
|
/// function layout
|
||||||
|
arg_layouts: &'a [Layout<'a>],
|
||||||
|
ret_layout: Layout<'a>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2703,6 +2706,11 @@ macro_rules! match_on_closure_argument {
|
||||||
|
|
||||||
let arena = $env.arena;
|
let arena = $env.arena;
|
||||||
|
|
||||||
|
let function_layout = arena.alloc(top_level).full();
|
||||||
|
|
||||||
|
let arg_layouts = top_level.arguments;
|
||||||
|
let ret_layout = top_level.result;
|
||||||
|
|
||||||
match closure_data_layout {
|
match closure_data_layout {
|
||||||
Layout::Closure(_, lambda_set, _) => {
|
Layout::Closure(_, lambda_set, _) => {
|
||||||
lowlevel_match_on_lambda_set(
|
lowlevel_match_on_lambda_set(
|
||||||
|
@ -2715,10 +2723,12 @@ macro_rules! match_on_closure_argument {
|
||||||
closure_layout: function_layout,
|
closure_layout: function_layout,
|
||||||
specialization_id,
|
specialization_id,
|
||||||
function_owns_closure_data: false,
|
function_owns_closure_data: false,
|
||||||
|
arg_layouts,
|
||||||
|
ret_layout,
|
||||||
},
|
},
|
||||||
arguments: arena.alloc([$($x,)* top_level_function, closure_data]),
|
arguments: arena.alloc([$($x,)* top_level_function, closure_data]),
|
||||||
},
|
},
|
||||||
arena.alloc(top_level).full(),
|
function_layout,
|
||||||
$layout,
|
$layout,
|
||||||
$assigned,
|
$assigned,
|
||||||
$hole,
|
$hole,
|
||||||
|
|
|
@ -43,6 +43,7 @@ pub enum Layout<'a> {
|
||||||
Struct(&'a [Layout<'a>]),
|
Struct(&'a [Layout<'a>]),
|
||||||
Union(UnionLayout<'a>),
|
Union(UnionLayout<'a>),
|
||||||
RecursivePointer,
|
RecursivePointer,
|
||||||
|
|
||||||
/// A function. The types of its arguments, then the type of its return value.
|
/// A function. The types of its arguments, then the type of its return value.
|
||||||
FunctionPointer(&'a [Layout<'a>], &'a Layout<'a>),
|
FunctionPointer(&'a [Layout<'a>], &'a Layout<'a>),
|
||||||
Closure(&'a [Layout<'a>], LambdaSet<'a>, &'a Layout<'a>),
|
Closure(&'a [Layout<'a>], LambdaSet<'a>, &'a Layout<'a>),
|
||||||
|
|
|
@ -6,5 +6,7 @@ platform examples/quicksort
|
||||||
provides [ mainForHost ]
|
provides [ mainForHost ]
|
||||||
effects fx.Effect {}
|
effects fx.Effect {}
|
||||||
|
|
||||||
|
update : Model -> Model
|
||||||
|
|
||||||
mainForHost : List I64 -> List I64
|
mainForHost : List I64 -> List I64
|
||||||
mainForHost = \list -> quicksort list
|
mainForHost = \list -> quicksort list
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue