mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
get poc-effect working
This commit is contained in:
parent
a055fa3626
commit
3c7e849830
5 changed files with 73 additions and 28 deletions
|
@ -3069,6 +3069,8 @@ pub fn build_proc_header_new<'a, 'ctx, 'env>(
|
||||||
) -> FunctionValue<'ctx> {
|
) -> FunctionValue<'ctx> {
|
||||||
let layout = env.arena.alloc(layout).full();
|
let layout = env.arena.alloc(layout).full();
|
||||||
|
|
||||||
|
dbg!(symbol, layout);
|
||||||
|
|
||||||
build_proc_header(env, layout_ids, symbol, &layout, proc)
|
build_proc_header(env, layout_ids, symbol, &layout, proc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ use roc_types::subs::{Content, FlatType, Subs, Variable};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder};
|
use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder};
|
||||||
|
|
||||||
pub const PRETTY_PRINT_IR_SYMBOLS: bool = false;
|
pub const PRETTY_PRINT_IR_SYMBOLS: bool = true;
|
||||||
|
|
||||||
macro_rules! return_on_layout_error {
|
macro_rules! return_on_layout_error {
|
||||||
($env:expr, $layout_result:expr) => {
|
($env:expr, $layout_result:expr) => {
|
||||||
|
@ -1946,7 +1946,7 @@ fn specialize_external<'a>(
|
||||||
args: &[],
|
args: &[],
|
||||||
body: specialized_body,
|
body: specialized_body,
|
||||||
closure_data_layout: Some(closure_data_layout),
|
closure_data_layout: Some(closure_data_layout),
|
||||||
ret_layout: closure_data_layout,
|
ret_layout,
|
||||||
is_self_recursive: recursivity,
|
is_self_recursive: recursivity,
|
||||||
must_own_arguments: false,
|
must_own_arguments: false,
|
||||||
host_exposed_layouts,
|
host_exposed_layouts,
|
||||||
|
@ -2257,7 +2257,48 @@ fn build_specialized_proc<'a>(
|
||||||
ret_layout,
|
ret_layout,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Some(_) | None => {
|
Some(lambda_set) => {
|
||||||
|
// a function that returns a function, but is not itself a closure
|
||||||
|
// e.g. f = Num.add
|
||||||
|
|
||||||
|
// make sure there is not arg_closure argument without a closure layout
|
||||||
|
debug_assert!(pattern_symbols.last() != Some(&Symbol::ARG_CLOSURE));
|
||||||
|
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
match pattern_layouts_len.cmp(&pattern_symbols.len()) {
|
||||||
|
Ordering::Equal => {
|
||||||
|
let proc_args = proc_args.into_bump_slice();
|
||||||
|
|
||||||
|
Ok(FunctionBody {
|
||||||
|
arguments: proc_args,
|
||||||
|
closure: None,
|
||||||
|
ret_layout,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Ordering::Greater => {
|
||||||
|
if pattern_symbols.is_empty() {
|
||||||
|
let ret_layout = lambda_set.runtime_representation();
|
||||||
|
Ok(FunctionPointerBody {
|
||||||
|
arguments: pattern_layouts_slice,
|
||||||
|
closure: None,
|
||||||
|
ret_layout,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// so far, the problem when hitting this branch was always somewhere else
|
||||||
|
// I think this branch should not be reachable in a bugfree compiler
|
||||||
|
panic!(
|
||||||
|
"more arguments (according to the layout) than argument symbols for {:?}",
|
||||||
|
proc_name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ordering::Less => panic!(
|
||||||
|
"more argument symbols than arguments (according to the layout) for {:?}",
|
||||||
|
proc_name
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
// else we're making a normal function, no closure problems to worry about
|
// else we're making a normal function, no closure problems to worry about
|
||||||
// we'll just assert some things
|
// we'll just assert some things
|
||||||
|
|
||||||
|
@ -2983,9 +3024,7 @@ pub fn with_hole<'a>(
|
||||||
"The `[]` type has no constructors, source var {:?}",
|
"The `[]` type has no constructors, source var {:?}",
|
||||||
variant_var
|
variant_var
|
||||||
),
|
),
|
||||||
Unit | UnitWithArguments => {
|
Unit | UnitWithArguments => let_empty_struct(assigned, hole),
|
||||||
Stmt::Let(assigned, Expr::Struct(&[]), Layout::Struct(&[]), hole)
|
|
||||||
}
|
|
||||||
BoolUnion { ttrue, .. } => Stmt::Let(
|
BoolUnion { ttrue, .. } => Stmt::Let(
|
||||||
assigned,
|
assigned,
|
||||||
Expr::Literal(Literal::Bool(tag_name == ttrue)),
|
Expr::Literal(Literal::Bool(tag_name == ttrue)),
|
||||||
|
@ -3334,7 +3373,7 @@ pub fn with_hole<'a>(
|
||||||
stmt
|
stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
EmptyRecord => Stmt::Let(assigned, Expr::Struct(&[]), Layout::Struct(&[]), hole),
|
EmptyRecord => let_empty_struct(assigned, hole),
|
||||||
|
|
||||||
Expect(_, _) => unreachable!("I think this is unreachable"),
|
Expect(_, _) => unreachable!("I think this is unreachable"),
|
||||||
|
|
||||||
|
@ -5678,9 +5717,7 @@ fn handle_variable_aliasing<'a>(
|
||||||
// then we must construct its closure; since imported symbols have no closure, we use the
|
// then we must construct its closure; since imported symbols have no closure, we use the
|
||||||
// empty struct
|
// empty struct
|
||||||
|
|
||||||
let layout = Layout::Struct(&[]);
|
let_empty_struct(left, env.arena.alloc(result))
|
||||||
let expr = Expr::Struct(&[]);
|
|
||||||
Stmt::Let(left, expr, layout, env.arena.alloc(result))
|
|
||||||
} else {
|
} else {
|
||||||
substitute_in_exprs(env.arena, &mut result, left, right);
|
substitute_in_exprs(env.arena, &mut result, left, right);
|
||||||
|
|
||||||
|
@ -5719,6 +5756,10 @@ fn force_thunk<'a>(
|
||||||
Stmt::Let(assigned, Expr::Call(call), layout, env.arena.alloc(hole))
|
Stmt::Let(assigned, Expr::Call(call), layout, env.arena.alloc(hole))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn let_empty_struct<'a>(assigned: Symbol, hole: &'a Stmt<'a>) -> Stmt<'a> {
|
||||||
|
Stmt::Let(assigned, Expr::Struct(&[]), Layout::Struct(&[]), hole)
|
||||||
|
}
|
||||||
|
|
||||||
/// If the symbol is a function, make sure it is properly specialized
|
/// If the symbol is a function, make sure it is properly specialized
|
||||||
fn reuse_function_symbol<'a>(
|
fn reuse_function_symbol<'a>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
|
@ -5745,12 +5786,7 @@ fn reuse_function_symbol<'a>(
|
||||||
|
|
||||||
// an imported symbol is either a function, or a top-level 0-argument thunk
|
// an imported symbol is either a function, or a top-level 0-argument thunk
|
||||||
// it never has closure data, so we use the empty struct
|
// it never has closure data, so we use the empty struct
|
||||||
return Stmt::Let(
|
return let_empty_struct(symbol, env.arena.alloc(result));
|
||||||
symbol,
|
|
||||||
Expr::Struct(&[]),
|
|
||||||
Layout::Struct(&[]),
|
|
||||||
env.arena.alloc(result),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -5816,12 +5852,20 @@ fn reuse_function_symbol<'a>(
|
||||||
env.arena.alloc(result),
|
env.arena.alloc(result),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return Stmt::Let(
|
debug_assert!(procs.module_thunks.contains(&original));
|
||||||
symbol,
|
|
||||||
Expr::Struct(&[]),
|
// this is a 0-argument thunk
|
||||||
Layout::Struct(&[]),
|
let layout = Layout::Closure(argument_layouts, lambda_set, ret_layout);
|
||||||
env.arena.alloc(result),
|
let top_level = TopLevelFunctionLayout::new(env.arena, &[], layout);
|
||||||
|
procs.insert_passed_by_name(
|
||||||
|
env,
|
||||||
|
arg_var,
|
||||||
|
original,
|
||||||
|
top_level,
|
||||||
|
layout_cache,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
force_thunk(env, original, layout, symbol, env.arena.alloc(result))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(layout) => {
|
Ok(layout) => {
|
||||||
|
|
|
@ -102,6 +102,7 @@ pub struct LambdaSet<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// representation of the closure *for a particular function*
|
/// representation of the closure *for a particular function*
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum ClosureRepresentation<'a> {
|
pub enum ClosureRepresentation<'a> {
|
||||||
/// the closure is represented as a union. Includes the tag ID!
|
/// the closure is represented as a union. Includes the tag ID!
|
||||||
Union {
|
Union {
|
||||||
|
|
|
@ -1013,7 +1013,6 @@ fn specialize_closure() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
|
||||||
fn io_poc_effect() {
|
fn io_poc_effect() {
|
||||||
assert_non_opt_evals_to!(
|
assert_non_opt_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
|
@ -1044,7 +1043,6 @@ fn io_poc_effect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
|
||||||
fn io_poc_desugared() {
|
fn io_poc_desugared() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
|
@ -1052,14 +1050,14 @@ fn io_poc_desugared() {
|
||||||
app "test" provides [ main ] to "./platform"
|
app "test" provides [ main ] to "./platform"
|
||||||
|
|
||||||
# succeed : a -> ({} -> a)
|
# succeed : a -> ({} -> a)
|
||||||
succeed = \x -> \{} -> x
|
succeed = \x -> \_ -> x
|
||||||
|
|
||||||
foo : {} -> F64
|
foo : Str -> F64
|
||||||
foo =
|
foo =
|
||||||
succeed 3.14
|
succeed 3.14
|
||||||
|
|
||||||
# runEffect : ({} -> a) -> a
|
# runEffect : ({} -> a) -> a
|
||||||
runEffect = \thunk -> thunk {}
|
runEffect = \thunk -> thunk ""
|
||||||
|
|
||||||
main : F64
|
main : F64
|
||||||
main =
|
main =
|
||||||
|
|
|
@ -275,7 +275,7 @@ pub fn helper<'a>(
|
||||||
mode,
|
mode,
|
||||||
);
|
);
|
||||||
|
|
||||||
// fn_val.print_to_stderr();
|
fn_val.print_to_stderr();
|
||||||
// module.print_to_stderr();
|
// module.print_to_stderr();
|
||||||
|
|
||||||
panic!(
|
panic!(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue