mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
Implement List.map4
This commit is contained in:
parent
b29a029a33
commit
f9ed060e49
16 changed files with 419 additions and 16 deletions
|
@ -771,6 +771,37 @@ fn call_spec(
|
|||
builder.add_call(block, spec_var, module, name, argument)?;
|
||||
}
|
||||
|
||||
ListMap4 { xs, ys, zs, ws } => {
|
||||
let list1 = env.symbols[xs];
|
||||
let list2 = env.symbols[ys];
|
||||
let list3 = env.symbols[zs];
|
||||
let list4 = env.symbols[ws];
|
||||
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 bag4 = builder.add_get_tuple_field(block, list4, LIST_BAG_INDEX)?;
|
||||
let _cell4 = builder.add_get_tuple_field(block, list4, LIST_CELL_INDEX)?;
|
||||
let elem4 = builder.add_bag_get(block, bag4)?;
|
||||
|
||||
let argument = if closure_env_layout.is_none() {
|
||||
builder.add_make_tuple(block, &[elem1, elem2, elem3, elem4])?
|
||||
} else {
|
||||
builder.add_make_tuple(block, &[elem1, elem2, elem3, elem4, 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];
|
||||
|
|
|
@ -651,6 +651,21 @@ impl<'a> BorrowInfState<'a> {
|
|||
self.own_var(*zs);
|
||||
}
|
||||
}
|
||||
ListMap4 { xs, ys, zs, ws } => {
|
||||
// own the lists if the function wants to own the element
|
||||
if !function_ps[0].borrow {
|
||||
self.own_var(*xs);
|
||||
}
|
||||
if !function_ps[1].borrow {
|
||||
self.own_var(*ys);
|
||||
}
|
||||
if !function_ps[2].borrow {
|
||||
self.own_var(*zs);
|
||||
}
|
||||
if !function_ps[3].borrow {
|
||||
self.own_var(*ws);
|
||||
}
|
||||
}
|
||||
ListSortWith { xs } => {
|
||||
// always own the input list
|
||||
self.own_var(*xs);
|
||||
|
@ -933,6 +948,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
|||
ListMap | ListMapWithIndex => arena.alloc_slice_copy(&[owned, function, closure_data]),
|
||||
ListMap2 => arena.alloc_slice_copy(&[owned, owned, function, closure_data]),
|
||||
ListMap3 => arena.alloc_slice_copy(&[owned, owned, owned, function, closure_data]),
|
||||
ListMap4 => arena.alloc_slice_copy(&[owned, owned, owned, owned, function, closure_data]),
|
||||
ListKeepIf | ListKeepOks | ListKeepErrs => {
|
||||
arena.alloc_slice_copy(&[owned, function, closure_data])
|
||||
}
|
||||
|
|
|
@ -576,6 +576,27 @@ impl<'a> Context<'a> {
|
|||
|
||||
&*self.arena.alloc(Stmt::Let(z, v, l, b))
|
||||
}
|
||||
ListMap4 { xs, ys, zs, ws } => {
|
||||
let borrows = [
|
||||
function_ps[0].borrow,
|
||||
function_ps[1].borrow,
|
||||
function_ps[2].borrow,
|
||||
function_ps[3].borrow,
|
||||
FUNCTION,
|
||||
CLOSURE_DATA,
|
||||
];
|
||||
|
||||
let b = self.add_dec_after_lowlevel(arguments, &borrows, b, b_live_vars);
|
||||
|
||||
let b = decref_if_owned!(function_ps[0].borrow, *xs, b);
|
||||
let b = decref_if_owned!(function_ps[1].borrow, *ys, b);
|
||||
let b = decref_if_owned!(function_ps[2].borrow, *zs, b);
|
||||
let b = decref_if_owned!(function_ps[3].borrow, *ws, b);
|
||||
|
||||
let v = create_call!(function_ps.get(3));
|
||||
|
||||
&*self.arena.alloc(Stmt::Let(z, v, l, b))
|
||||
}
|
||||
ListMapWithIndex { xs } => {
|
||||
let borrows = [function_ps[1].borrow, FUNCTION, CLOSURE_DATA];
|
||||
|
||||
|
|
|
@ -4134,6 +4134,16 @@ pub fn with_hole<'a>(
|
|||
|
||||
match_on_closure_argument!(ListMap3, [xs, ys, zs])
|
||||
}
|
||||
ListMap4 => {
|
||||
debug_assert_eq!(arg_symbols.len(), 5);
|
||||
|
||||
let xs = arg_symbols[0];
|
||||
let ys = arg_symbols[1];
|
||||
let zs = arg_symbols[2];
|
||||
let ws = arg_symbols[3];
|
||||
|
||||
match_on_closure_argument!(ListMap4, [xs, ys, zs, ws])
|
||||
}
|
||||
_ => {
|
||||
let call = self::Call {
|
||||
call_type: CallType::LowLevel {
|
||||
|
|
|
@ -2,18 +2,55 @@ use roc_module::symbol::Symbol;
|
|||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum HigherOrder {
|
||||
ListMap { xs: Symbol },
|
||||
ListMap2 { xs: Symbol, ys: Symbol },
|
||||
ListMap3 { xs: Symbol, ys: Symbol, zs: Symbol },
|
||||
ListMapWithIndex { xs: Symbol },
|
||||
ListKeepIf { xs: Symbol },
|
||||
ListWalk { xs: Symbol, state: Symbol },
|
||||
ListWalkUntil { xs: Symbol, state: Symbol },
|
||||
ListWalkBackwards { xs: Symbol, state: Symbol },
|
||||
ListKeepOks { xs: Symbol },
|
||||
ListKeepErrs { xs: Symbol },
|
||||
ListSortWith { xs: Symbol },
|
||||
DictWalk { xs: Symbol, state: Symbol },
|
||||
ListMap {
|
||||
xs: Symbol,
|
||||
},
|
||||
ListMap2 {
|
||||
xs: Symbol,
|
||||
ys: Symbol,
|
||||
},
|
||||
ListMap3 {
|
||||
xs: Symbol,
|
||||
ys: Symbol,
|
||||
zs: Symbol,
|
||||
},
|
||||
ListMap4 {
|
||||
xs: Symbol,
|
||||
ys: Symbol,
|
||||
zs: Symbol,
|
||||
ws: Symbol,
|
||||
},
|
||||
ListMapWithIndex {
|
||||
xs: Symbol,
|
||||
},
|
||||
ListKeepIf {
|
||||
xs: Symbol,
|
||||
},
|
||||
ListWalk {
|
||||
xs: Symbol,
|
||||
state: Symbol,
|
||||
},
|
||||
ListWalkUntil {
|
||||
xs: Symbol,
|
||||
state: Symbol,
|
||||
},
|
||||
ListWalkBackwards {
|
||||
xs: Symbol,
|
||||
state: Symbol,
|
||||
},
|
||||
ListKeepOks {
|
||||
xs: Symbol,
|
||||
},
|
||||
ListKeepErrs {
|
||||
xs: Symbol,
|
||||
},
|
||||
ListSortWith {
|
||||
xs: Symbol,
|
||||
},
|
||||
DictWalk {
|
||||
xs: Symbol,
|
||||
state: Symbol,
|
||||
},
|
||||
}
|
||||
|
||||
impl HigherOrder {
|
||||
|
@ -22,6 +59,7 @@ impl HigherOrder {
|
|||
HigherOrder::ListMap { .. } => 1,
|
||||
HigherOrder::ListMap2 { .. } => 2,
|
||||
HigherOrder::ListMap3 { .. } => 3,
|
||||
HigherOrder::ListMap4 { .. } => 4,
|
||||
HigherOrder::ListMapWithIndex { .. } => 2,
|
||||
HigherOrder::ListKeepIf { .. } => 1,
|
||||
HigherOrder::ListWalk { .. } => 2,
|
||||
|
@ -258,6 +296,17 @@ fn from_low_level(low_level: &LowLevel, arguments: &[Symbol]) -> FirstOrHigher {
|
|||
function_env: arguments[4],
|
||||
})
|
||||
}
|
||||
LowLevel::ListMap4 => {
|
||||
debug_assert_eq!(arguments.len(), 6);
|
||||
Higher(ListMap4 {
|
||||
xs: arguments[0],
|
||||
ys: arguments[1],
|
||||
zs: arguments[2],
|
||||
ws: arguments[3],
|
||||
function_name: arguments[4],
|
||||
function_env: arguments[5],
|
||||
})
|
||||
}
|
||||
LowLevel::ListMapWithIndex => {
|
||||
debug_assert_eq!(arguments.len(), 3);
|
||||
Higher(ListMapWithIndex {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue