mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
module thunk is function
This commit is contained in:
parent
43c4f24515
commit
3b47fbc89a
3 changed files with 76 additions and 13 deletions
|
@ -2048,8 +2048,6 @@ fn update<'a>(
|
||||||
&& state.dependencies.solved_all()
|
&& state.dependencies.solved_all()
|
||||||
&& state.goal_phase == Phase::MakeSpecializations
|
&& state.goal_phase == Phase::MakeSpecializations
|
||||||
{
|
{
|
||||||
Proc::insert_refcount_operations(arena, &mut state.procedures);
|
|
||||||
|
|
||||||
// display the mono IR of the module, for debug purposes
|
// display the mono IR of the module, for debug purposes
|
||||||
if roc_mono::ir::PRETTY_PRINT_IR_SYMBOLS {
|
if roc_mono::ir::PRETTY_PRINT_IR_SYMBOLS {
|
||||||
let procs_string = state
|
let procs_string = state
|
||||||
|
@ -2062,6 +2060,7 @@ fn update<'a>(
|
||||||
|
|
||||||
println!("{}", result);
|
println!("{}", result);
|
||||||
}
|
}
|
||||||
|
Proc::insert_refcount_operations(arena, &mut state.procedures);
|
||||||
|
|
||||||
Proc::optimize_refcount_operations(
|
Proc::optimize_refcount_operations(
|
||||||
arena,
|
arena,
|
||||||
|
|
|
@ -6079,17 +6079,65 @@ fn call_by_name<'a>(
|
||||||
}
|
}
|
||||||
Ok(layout) if procs.module_thunks.contains(&proc_name) => {
|
Ok(layout) if procs.module_thunks.contains(&proc_name) => {
|
||||||
// here we turn a call to a module thunk into forcing of that thunk
|
// here we turn a call to a module thunk into forcing of that thunk
|
||||||
debug_assert!(loc_args.is_empty());
|
if loc_args.is_empty() {
|
||||||
call_by_name_module_thunk(
|
call_by_name_module_thunk(
|
||||||
env,
|
env,
|
||||||
procs,
|
procs,
|
||||||
fn_var,
|
fn_var,
|
||||||
proc_name,
|
proc_name,
|
||||||
env.arena.alloc(layout),
|
env.arena.alloc(layout),
|
||||||
layout_cache,
|
layout_cache,
|
||||||
assigned,
|
assigned,
|
||||||
hole,
|
hole,
|
||||||
)
|
)
|
||||||
|
} else if let Layout::Closure(arg_layouts, lambda_set, ret_layout) = layout {
|
||||||
|
// here we turn a call to a module thunk into forcing of that thunk
|
||||||
|
// the thunk represents the closure environment for the body, so we then match
|
||||||
|
// on the closure environment to perform the call that the body represents.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// > main = parseA "foo" "bar"
|
||||||
|
// > parseA = Str.concat
|
||||||
|
|
||||||
|
let closure_data_symbol = env.unique_symbol();
|
||||||
|
|
||||||
|
let arena = env.arena;
|
||||||
|
let arg_symbols = Vec::from_iter_in(
|
||||||
|
loc_args
|
||||||
|
.iter()
|
||||||
|
.map(|(_, arg_expr)| possible_reuse_symbol(env, procs, &arg_expr.value)),
|
||||||
|
arena,
|
||||||
|
)
|
||||||
|
.into_bump_slice();
|
||||||
|
|
||||||
|
let result = match_on_lambda_set(
|
||||||
|
env,
|
||||||
|
lambda_set,
|
||||||
|
closure_data_symbol,
|
||||||
|
arg_symbols,
|
||||||
|
arg_layouts,
|
||||||
|
*ret_layout,
|
||||||
|
assigned,
|
||||||
|
hole,
|
||||||
|
);
|
||||||
|
|
||||||
|
let result = call_by_name_module_thunk(
|
||||||
|
env,
|
||||||
|
procs,
|
||||||
|
fn_var,
|
||||||
|
proc_name,
|
||||||
|
env.arena.alloc(layout),
|
||||||
|
layout_cache,
|
||||||
|
closure_data_symbol,
|
||||||
|
env.arena.alloc(result),
|
||||||
|
);
|
||||||
|
|
||||||
|
let iter = loc_args.into_iter().rev().zip(arg_symbols.iter().rev());
|
||||||
|
assign_to_symbols(env, procs, layout_cache, iter, result)
|
||||||
|
} else {
|
||||||
|
unreachable!("calling a non-closure layout")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(Layout::FunctionPointer(argument_layouts, ret_layout)) => call_by_name_help(
|
Ok(Layout::FunctionPointer(argument_layouts, ret_layout)) => call_by_name_help(
|
||||||
env,
|
env,
|
||||||
|
|
|
@ -2426,3 +2426,19 @@ fn increment_or_double_closure() {
|
||||||
i64
|
i64
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn module_thunk_is_function() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" provides [ main ] to "./platform"
|
||||||
|
|
||||||
|
main = helper "foo" "bar"
|
||||||
|
helper = Str.concat
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
RocStr::from_slice(b"foobar"),
|
||||||
|
RocStr
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue