mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
working Set.walk
This commit is contained in:
parent
d25b1dc549
commit
ca78439756
8 changed files with 471 additions and 576 deletions
File diff suppressed because it is too large
Load diff
|
@ -145,6 +145,7 @@ fn build_transform_caller_help_new<'a, 'ctx, 'env>(
|
||||||
arguments_cast.push(argument);
|
arguments_cast.push(argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbg!(closure_data_layout);
|
||||||
match closure_data_layout {
|
match closure_data_layout {
|
||||||
Layout::FunctionPointer(_, _) => {
|
Layout::FunctionPointer(_, _) => {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
@ -167,9 +168,31 @@ fn build_transform_caller_help_new<'a, 'ctx, 'env>(
|
||||||
arguments_cast.push(closure_data);
|
arguments_cast.push(closure_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Layout::Struct([Layout::Closure(_, lambda_set, _)]) => {
|
||||||
|
// a case required for Set.walk; may be able to remove when we can define builtins in
|
||||||
|
// terms of other builtins in the right way (using their function symbols instead of
|
||||||
|
// hacking with lowlevel ops).
|
||||||
|
let closure_type = basic_type_from_layout(
|
||||||
|
env,
|
||||||
|
&Layout::Struct(&[lambda_set.runtime_representation()]),
|
||||||
|
)
|
||||||
|
.ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
|
let closure_cast = env
|
||||||
|
.builder
|
||||||
|
.build_bitcast(closure_ptr, closure_type, "load_opaque")
|
||||||
|
.into_pointer_value();
|
||||||
|
|
||||||
|
let closure_data = env.builder.build_load(closure_cast, "load_opaque");
|
||||||
|
|
||||||
|
arguments_cast.push(closure_data);
|
||||||
|
}
|
||||||
Layout::Struct([]) => {
|
Layout::Struct([]) => {
|
||||||
// do nothing, should try to remove this case later
|
// do nothing, should try to remove this case later
|
||||||
}
|
}
|
||||||
|
Layout::Struct(_) => {
|
||||||
|
// do nothing, should try to remove this case later
|
||||||
|
}
|
||||||
other => unreachable!("layout is not valid for a closure: {:?}", other),
|
other => unreachable!("layout is not valid for a closure: {:?}", other),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3069,8 +3069,6 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4448,11 +4446,12 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DictWalk => {
|
DictWalk => {
|
||||||
debug_assert_eq!(args.len(), 3);
|
debug_assert_eq!(args.len(), 4);
|
||||||
|
|
||||||
let (dict, dict_layout) = load_symbol_and_layout(scope, &args[0]);
|
let (dict, dict_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||||
let (stepper, stepper_layout) = load_symbol_and_layout(scope, &args[1]);
|
let (default, default_layout) = load_symbol_and_layout(scope, &args[1]);
|
||||||
let (accum, accum_layout) = load_symbol_and_layout(scope, &args[2]);
|
let (function_layout, function) = scope.function_pointers[&args[2]];
|
||||||
|
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[3]);
|
||||||
|
|
||||||
match dict_layout {
|
match dict_layout {
|
||||||
Layout::Builtin(Builtin::EmptyDict) => {
|
Layout::Builtin(Builtin::EmptyDict) => {
|
||||||
|
@ -4463,12 +4462,14 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
env,
|
env,
|
||||||
layout_ids,
|
layout_ids,
|
||||||
dict,
|
dict,
|
||||||
stepper,
|
function,
|
||||||
accum,
|
function_layout,
|
||||||
stepper_layout,
|
closure,
|
||||||
|
*closure_layout,
|
||||||
|
default,
|
||||||
key_layout,
|
key_layout,
|
||||||
value_layout,
|
value_layout,
|
||||||
accum_layout,
|
default_layout,
|
||||||
),
|
),
|
||||||
_ => unreachable!("invalid dict layout"),
|
_ => unreachable!("invalid dict layout"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::debug_info_init;
|
use crate::debug_info_init;
|
||||||
use crate::llvm::bitcode::{
|
use crate::llvm::bitcode::{
|
||||||
build_dec_wrapper, build_eq_wrapper, build_inc_wrapper, build_transform_caller,
|
build_dec_wrapper, build_eq_wrapper, build_inc_wrapper, build_transform_caller_new,
|
||||||
call_bitcode_fn, call_void_bitcode_fn,
|
call_bitcode_fn, call_void_bitcode_fn,
|
||||||
};
|
};
|
||||||
use crate::llvm::build::{
|
use crate::llvm::build::{
|
||||||
|
@ -633,9 +633,11 @@ pub fn dict_walk<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
layout_ids: &mut LayoutIds<'a>,
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
dict: BasicValueEnum<'ctx>,
|
dict: BasicValueEnum<'ctx>,
|
||||||
stepper: BasicValueEnum<'ctx>,
|
transform: FunctionValue<'ctx>,
|
||||||
|
transform_layout: Layout<'a>,
|
||||||
|
closure_data: BasicValueEnum<'ctx>,
|
||||||
|
closure_data_layout: Layout<'a>,
|
||||||
accum: BasicValueEnum<'ctx>,
|
accum: BasicValueEnum<'ctx>,
|
||||||
stepper_layout: &Layout<'a>,
|
|
||||||
key_layout: &Layout<'a>,
|
key_layout: &Layout<'a>,
|
||||||
value_layout: &Layout<'a>,
|
value_layout: &Layout<'a>,
|
||||||
accum_layout: &Layout<'a>,
|
accum_layout: &Layout<'a>,
|
||||||
|
@ -648,13 +650,13 @@ pub fn dict_walk<'a, 'ctx, 'env>(
|
||||||
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
||||||
env.builder.build_store(dict_ptr, dict);
|
env.builder.build_store(dict_ptr, dict);
|
||||||
|
|
||||||
let stepper_ptr = builder.build_alloca(stepper.get_type(), "stepper_ptr");
|
let closure_data_ptr = builder.build_alloca(closure_data.get_type(), "closure_data_ptr");
|
||||||
env.builder.build_store(stepper_ptr, stepper);
|
env.builder.build_store(closure_data_ptr, closure_data);
|
||||||
|
|
||||||
let stepper_caller = build_transform_caller(
|
let stepper_caller = build_transform_caller_new(
|
||||||
env,
|
env,
|
||||||
layout_ids,
|
transform,
|
||||||
stepper_layout,
|
closure_data_layout,
|
||||||
&[*key_layout, *value_layout, *accum_layout],
|
&[*key_layout, *value_layout, *accum_layout],
|
||||||
)
|
)
|
||||||
.as_global_value()
|
.as_global_value()
|
||||||
|
@ -688,7 +690,8 @@ pub fn dict_walk<'a, 'ctx, 'env>(
|
||||||
env,
|
env,
|
||||||
&[
|
&[
|
||||||
dict_ptr.into(),
|
dict_ptr.into(),
|
||||||
env.builder.build_bitcast(stepper_ptr, u8_ptr, "to_opaque"),
|
env.builder
|
||||||
|
.build_bitcast(closure_data_ptr, u8_ptr, "to_opaque"),
|
||||||
stepper_caller.into(),
|
stepper_caller.into(),
|
||||||
env.builder.build_bitcast(accum_ptr, u8_ptr, "to_opaque"),
|
env.builder.build_bitcast(accum_ptr, u8_ptr, "to_opaque"),
|
||||||
alignment_iv.into(),
|
alignment_iv.into(),
|
||||||
|
|
|
@ -980,6 +980,7 @@ define_builtins! {
|
||||||
12 SET_WALK: "walk"
|
12 SET_WALK: "walk"
|
||||||
13 SET_WALK_USER_FUNCTION: "#walk_user_function"
|
13 SET_WALK_USER_FUNCTION: "#walk_user_function"
|
||||||
14 SET_CONTAINS: "contains"
|
14 SET_CONTAINS: "contains"
|
||||||
|
15 SET_WALK_VAR: "#set_walk_var"
|
||||||
}
|
}
|
||||||
|
|
||||||
num_modules: 8 // Keep this count up to date by hand! (TODO: see the mut_map! macro for how we could determine this count correctly in the macro)
|
num_modules: 8 // Keep this count up to date by hand! (TODO: see the mut_map! macro for how we could determine this count correctly in the macro)
|
||||||
|
|
|
@ -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 = true;
|
pub const PRETTY_PRINT_IR_SYMBOLS: bool = false;
|
||||||
|
|
||||||
macro_rules! return_on_layout_error {
|
macro_rules! return_on_layout_error {
|
||||||
($env:expr, $layout_result:expr) => {
|
($env:expr, $layout_result:expr) => {
|
||||||
|
@ -2449,8 +2449,8 @@ impl<'a> TopLevelFunctionLayout<'a> {
|
||||||
Layout::FunctionPointer(old_arguments, result) => {
|
Layout::FunctionPointer(old_arguments, result) => {
|
||||||
Self::new(arena, old_arguments, *result)
|
Self::new(arena, old_arguments, *result)
|
||||||
}
|
}
|
||||||
Layout::Closure(arguments, closure_layout, result) => {
|
Layout::Closure(arguments, lambda_set, result) => {
|
||||||
let full = closure_layout.extend_function_layout(arena, arguments, result);
|
let full = lambda_set.extend_function_layout(arena, arguments, result);
|
||||||
TopLevelFunctionLayout::from_layout(arena, full)
|
TopLevelFunctionLayout::from_layout(arena, full)
|
||||||
}
|
}
|
||||||
_ => TopLevelFunctionLayout {
|
_ => TopLevelFunctionLayout {
|
||||||
|
@ -3901,7 +3901,7 @@ pub fn with_hole<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
Call(boxed, loc_args, _) => {
|
Call(boxed, loc_args, _) => {
|
||||||
let (fn_var, loc_expr, lambda_set_var, ret_var) = *boxed;
|
let (fn_var, loc_expr, _lambda_set_var, ret_var) = *boxed;
|
||||||
|
|
||||||
// even if a call looks like it's by name, it may in fact be by-pointer.
|
// even if a call looks like it's by name, it may in fact be by-pointer.
|
||||||
// E.g. in `(\f, x -> f x)` the call is in fact by pointer.
|
// E.g. in `(\f, x -> f x)` the call is in fact by pointer.
|
||||||
|
@ -3910,7 +3910,7 @@ pub fn with_hole<'a>(
|
||||||
// if it's in there, it's a call by name, otherwise it's a call by pointer
|
// if it's in there, it's a call by name, otherwise it's a call by pointer
|
||||||
let is_known = |key| {
|
let is_known = |key| {
|
||||||
// a proc in this module, or an imported symbol
|
// a proc in this module, or an imported symbol
|
||||||
procs.partial_procs.contains_key(key) || key.module_id() != assigned.module_id()
|
procs.partial_procs.contains_key(key) || env.is_imported_symbol(*key)
|
||||||
};
|
};
|
||||||
|
|
||||||
match loc_expr.value {
|
match loc_expr.value {
|
||||||
|
@ -4181,6 +4181,16 @@ pub fn with_hole<'a>(
|
||||||
// actual closure, and the default is either the number 1 or 0
|
// actual closure, and the default is either the number 1 or 0
|
||||||
// this can be removed when we define builtin modules as proper modules
|
// this can be removed when we define builtin modules as proper modules
|
||||||
|
|
||||||
|
let stmt = assign_to_symbol(
|
||||||
|
env,
|
||||||
|
procs,
|
||||||
|
layout_cache,
|
||||||
|
args[0].0,
|
||||||
|
Located::at_zero(args[0].1.clone()),
|
||||||
|
arg_symbols[0],
|
||||||
|
stmt,
|
||||||
|
);
|
||||||
|
|
||||||
let stmt = assign_to_symbol(
|
let stmt = assign_to_symbol(
|
||||||
env,
|
env,
|
||||||
procs,
|
procs,
|
||||||
|
@ -7524,8 +7534,7 @@ fn lowlevel_match_on_lambda_set<'a, F>(
|
||||||
where
|
where
|
||||||
F: Fn(Symbol, Symbol) -> Call<'a> + Copy,
|
F: Fn(Symbol, Symbol) -> Call<'a> + Copy,
|
||||||
{
|
{
|
||||||
dbg!(lambda_set);
|
match lambda_set.runtime_representation() {
|
||||||
match dbg!(lambda_set.runtime_representation()) {
|
|
||||||
Layout::Union(_) => {
|
Layout::Union(_) => {
|
||||||
let closure_tag_id_symbol = env.unique_symbol();
|
let closure_tag_id_symbol = env.unique_symbol();
|
||||||
|
|
||||||
|
@ -7562,8 +7571,6 @@ where
|
||||||
|
|
||||||
let bound = env.unique_symbol();
|
let bound = env.unique_symbol();
|
||||||
|
|
||||||
dbg!(hole);
|
|
||||||
|
|
||||||
// build the call
|
// build the call
|
||||||
let stmt = Stmt::Let(
|
let stmt = Stmt::Let(
|
||||||
assigned,
|
assigned,
|
||||||
|
|
|
@ -168,6 +168,7 @@ impl<'a> LambdaSet<'a> {
|
||||||
) -> Layout<'a> {
|
) -> Layout<'a> {
|
||||||
if let [] = self.set {
|
if let [] = self.set {
|
||||||
// TERRIBLE HACK for builting functions
|
// TERRIBLE HACK for builting functions
|
||||||
|
panic!();
|
||||||
Layout::FunctionPointer(argument_layouts, ret_layout)
|
Layout::FunctionPointer(argument_layouts, ret_layout)
|
||||||
} else {
|
} else {
|
||||||
match self.representation {
|
match self.representation {
|
||||||
|
|
|
@ -1809,12 +1809,7 @@ fn list_keep_errs() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
mapErr = \result, f ->
|
List.keepErrs [0,1,2] (\x -> x % 0 |> Result.mapErr (\_ -> 32))
|
||||||
when result is
|
|
||||||
Err e -> Err ( f e )
|
|
||||||
Ok v -> Ok v
|
|
||||||
|
|
||||||
List.keepErrs [0,1,2] (\x -> x % 0 |> mapErr (\_ -> 32))
|
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
&[32, 32, 32],
|
&[32, 32, 32],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue