mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Add builtin List.intersperse
This commit is contained in:
parent
8f25106b2c
commit
16fb04b4fa
5 changed files with 120 additions and 0 deletions
|
@ -111,6 +111,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
|||
LIST_WALK_UNTIL => list_walk_until,
|
||||
LIST_SORT_WITH => list_sort_with,
|
||||
LIST_ANY => list_any,
|
||||
LIST_INTERSPERSE => list_intersperse,
|
||||
LIST_FIND => list_find,
|
||||
DICT_LEN => dict_len,
|
||||
DICT_EMPTY => dict_empty,
|
||||
|
@ -2147,6 +2148,82 @@ fn list_sublist(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|||
)
|
||||
}
|
||||
|
||||
/// List.intersperse : List elem, elem -> List elem
|
||||
fn list_intersperse(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let list_var = var_store.fresh();
|
||||
let sep_var = var_store.fresh();
|
||||
|
||||
let list_sym = Symbol::ARG_1;
|
||||
let sep_sym = Symbol::ARG_2;
|
||||
|
||||
let clos_var = var_store.fresh();
|
||||
let clos_acc_var = var_store.fresh();
|
||||
|
||||
let clos_sym = Symbol::LIST_INTERSPERSE_CLOS;
|
||||
let clos_acc_sym = Symbol::ARG_3;
|
||||
let clos_elem_sym = Symbol::ARG_4;
|
||||
|
||||
let int_var = var_store.fresh();
|
||||
let zero = int(int_var, Variable::NATURAL, 0);
|
||||
|
||||
// \elem -> [sep, elem]
|
||||
let clos = Closure(ClosureData {
|
||||
function_type: clos_var,
|
||||
closure_type: var_store.fresh(),
|
||||
closure_ext_var: var_store.fresh(),
|
||||
return_type: clos_acc_var,
|
||||
name: clos_sym,
|
||||
recursive: Recursive::NotRecursive,
|
||||
captured_symbols: vec![(sep_sym, sep_var)],
|
||||
arguments: vec![
|
||||
(clos_acc_var, no_region(Pattern::Identifier(clos_acc_sym))),
|
||||
(sep_var, no_region(Pattern::Identifier(clos_elem_sym))),
|
||||
],
|
||||
loc_body: {
|
||||
let pair = List {
|
||||
elem_var: sep_var,
|
||||
loc_elems: vec![no_region(Var(sep_sym)), no_region(Var(clos_elem_sym))],
|
||||
};
|
||||
Box::new(no_region(RunLowLevel {
|
||||
op: LowLevel::ListConcat,
|
||||
args: vec![(clos_acc_var, Var(clos_acc_sym)), (clos_acc_var, pair)],
|
||||
ret_var: clos_acc_var,
|
||||
}))
|
||||
},
|
||||
});
|
||||
|
||||
// List.walk [] l (\acc, elem -> List.concat acc [sep, elem])
|
||||
let acc = RunLowLevel {
|
||||
op: LowLevel::ListWalk,
|
||||
args: vec![
|
||||
(list_var, Var(list_sym)),
|
||||
(
|
||||
clos_acc_var,
|
||||
List {
|
||||
elem_var: sep_var,
|
||||
loc_elems: vec![],
|
||||
},
|
||||
),
|
||||
(clos_var, clos),
|
||||
],
|
||||
ret_var: clos_acc_var,
|
||||
};
|
||||
|
||||
let body = RunLowLevel {
|
||||
op: LowLevel::ListDropAt,
|
||||
args: vec![(clos_acc_var, acc), (int_var, zero)],
|
||||
ret_var: clos_acc_var,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(list_var, list_sym), (sep_var, sep_sym)],
|
||||
var_store,
|
||||
body,
|
||||
clos_acc_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.drop : List elem, Nat -> List elem
|
||||
fn list_drop(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let list_var = var_store.fresh();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue