mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
List.walkRight definition in unique, std, builtins, etc. No implementation
This commit is contained in:
parent
e69595b794
commit
5d0ec57461
9 changed files with 82 additions and 24 deletions
|
@ -491,6 +491,19 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// walkRight : List elem, (elem -> accum -> accum), accum -> accum
|
||||||
|
add_type(
|
||||||
|
Symbol::LIST_WALK_RIGHT,
|
||||||
|
SolvedType::Func(
|
||||||
|
vec![
|
||||||
|
list_type(flex(TVAR1)),
|
||||||
|
SolvedType::Func(vec![flex(TVAR1), flex(TVAR2)], Box::new(flex(TVAR2))),
|
||||||
|
flex(TVAR2),
|
||||||
|
],
|
||||||
|
Box::new(flex(TVAR2)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
// keepIf : List elem, (elem -> Bool) -> List elem
|
// keepIf : List elem, (elem -> Bool) -> List elem
|
||||||
add_type(
|
add_type(
|
||||||
Symbol::LIST_KEEP_IF,
|
Symbol::LIST_KEEP_IF,
|
||||||
|
@ -515,19 +528,6 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// foldr : List a, (a -> b -> b), b -> b
|
|
||||||
add_type(
|
|
||||||
Symbol::LIST_FOLDR,
|
|
||||||
SolvedType::Func(
|
|
||||||
vec![
|
|
||||||
list_type(flex(TVAR1)),
|
|
||||||
SolvedType::Func(vec![flex(TVAR1), flex(TVAR2)], Box::new(flex(TVAR2))),
|
|
||||||
flex(TVAR2),
|
|
||||||
],
|
|
||||||
Box::new(flex(TVAR2)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// append : List elem, elem -> List elem
|
// append : List elem, elem -> List elem
|
||||||
add_type(
|
add_type(
|
||||||
Symbol::LIST_APPEND,
|
Symbol::LIST_APPEND,
|
||||||
|
|
|
@ -784,8 +784,8 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
});
|
});
|
||||||
|
|
||||||
// keepIf : Attr * (List a)
|
// keepIf : Attr * (List a)
|
||||||
// , Attr Shared (a -> Attr * Bool)
|
// , Attr Shared (a -> Attr * Bool)
|
||||||
// -> Attr * (List a)
|
// -> Attr * (List a)
|
||||||
add_type(Symbol::LIST_KEEP_IF, {
|
add_type(Symbol::LIST_KEEP_IF, {
|
||||||
let_tvars! { a, star1, star2, star3 };
|
let_tvars! { a, star1, star2, star3 };
|
||||||
|
|
||||||
|
@ -798,11 +798,11 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
// foldr : Attr (* | u) (List (Attr u a))
|
// walkRight : Attr (* | u) (List (Attr u a))
|
||||||
// , Attr Shared (Attr u a -> b -> b)
|
// , Attr Shared (Attr u a -> b -> b)
|
||||||
// , b
|
// , b
|
||||||
// -> b
|
// -> b
|
||||||
add_type(Symbol::LIST_FOLDR, {
|
add_type(Symbol::LIST_WALK_RIGHT, {
|
||||||
let_tvars! { u, a, b, star1 };
|
let_tvars! { u, a, b, star1 };
|
||||||
|
|
||||||
unique_function(
|
unique_function(
|
||||||
|
|
|
@ -65,6 +65,7 @@ pub fn builtin_defs(var_store: &mut VarStore) -> MutMap<Symbol, Def> {
|
||||||
Symbol::LIST_JOIN => list_join,
|
Symbol::LIST_JOIN => list_join,
|
||||||
Symbol::LIST_MAP => list_map,
|
Symbol::LIST_MAP => list_map,
|
||||||
Symbol::LIST_KEEP_IF => list_keep_if,
|
Symbol::LIST_KEEP_IF => list_keep_if,
|
||||||
|
Symbol::LIST_WALK_RIGHT => list_walk_right,
|
||||||
Symbol::NUM_ADD => num_add,
|
Symbol::NUM_ADD => num_add,
|
||||||
Symbol::NUM_SUB => num_sub,
|
Symbol::NUM_SUB => num_sub,
|
||||||
Symbol::NUM_MUL => num_mul,
|
Symbol::NUM_MUL => num_mul,
|
||||||
|
@ -946,6 +947,35 @@ fn list_join(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// List.walkRight : List elem, (elem -> accum -> accum), accum -> accum
|
||||||
|
fn list_walk_right(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
|
let list_var = var_store.fresh();
|
||||||
|
let func_var = var_store.fresh();
|
||||||
|
let accum_var = var_store.fresh();
|
||||||
|
|
||||||
|
let body = RunLowLevel {
|
||||||
|
op: LowLevel::ListWalkRight,
|
||||||
|
args: vec![
|
||||||
|
(list_var, Var(Symbol::ARG_1)),
|
||||||
|
(func_var, Var(Symbol::ARG_2)),
|
||||||
|
(accum_var, Var(Symbol::ARG_3)),
|
||||||
|
],
|
||||||
|
ret_var: list_var,
|
||||||
|
};
|
||||||
|
|
||||||
|
defn(
|
||||||
|
symbol,
|
||||||
|
vec![
|
||||||
|
(list_var, Symbol::ARG_1),
|
||||||
|
(func_var, Symbol::ARG_2),
|
||||||
|
(accum_var, Symbol::ARG_3),
|
||||||
|
],
|
||||||
|
var_store,
|
||||||
|
body,
|
||||||
|
list_var,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// List.keepIf : List elem, (elem -> Bool) -> List elem
|
/// List.keepIf : List elem, (elem -> Bool) -> List elem
|
||||||
fn list_keep_if(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn list_keep_if(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let list_var = var_store.fresh();
|
let list_var = var_store.fresh();
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::llvm::build_list::{
|
||||||
allocate_list, build_basic_phi2, clone_nonempty_list, empty_list, empty_polymorphic_list,
|
allocate_list, build_basic_phi2, clone_nonempty_list, empty_list, empty_polymorphic_list,
|
||||||
incrementing_elem_loop, list_append, list_concat, list_get_unsafe, list_is_not_empty,
|
incrementing_elem_loop, list_append, list_concat, list_get_unsafe, list_is_not_empty,
|
||||||
list_join, list_keep_if, list_len, list_map, list_prepend, list_repeat, list_reverse, list_set,
|
list_join, list_keep_if, list_len, list_map, list_prepend, list_repeat, list_reverse, list_set,
|
||||||
list_single, load_list_ptr, store_list, LoopListArg,
|
list_single, list_walk_right, load_list_ptr, store_list, LoopListArg,
|
||||||
};
|
};
|
||||||
use crate::llvm::compare::{build_eq, build_neq};
|
use crate::llvm::compare::{build_eq, build_neq};
|
||||||
use crate::llvm::convert::{
|
use crate::llvm::convert::{
|
||||||
|
@ -1707,6 +1707,12 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
list_keep_if(env, parent, func, func_layout, list, list_layout)
|
list_keep_if(env, parent, func, func_layout, list, list_layout)
|
||||||
}
|
}
|
||||||
|
ListWalkRight => {
|
||||||
|
// List.walkRight : List elem, (elem -> accum -> accum), accum -> accum
|
||||||
|
debug_assert_eq!(args.len(), 3);
|
||||||
|
|
||||||
|
list_walk_right(env)
|
||||||
|
}
|
||||||
ListAppend => {
|
ListAppend => {
|
||||||
// List.append : List elem, elem -> List elem
|
// List.append : List elem, elem -> List elem
|
||||||
debug_assert_eq!(args.len(), 2);
|
debug_assert_eq!(args.len(), 2);
|
||||||
|
|
|
@ -641,6 +641,13 @@ pub fn list_len<'ctx>(
|
||||||
.into_int_value()
|
.into_int_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// List.walkRight : List elem, (elem -> accum -> accum), accum -> accum
|
||||||
|
pub fn list_walk_right<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValueEnum<'ctx> {
|
||||||
|
let ctx = env.context;
|
||||||
|
|
||||||
|
BasicValueEnum::IntValue(ctx.i64_type().const_int(0 as u64, false))
|
||||||
|
}
|
||||||
|
|
||||||
/// List.keepIf : List elem, (elem -> Bool) -> List elem
|
/// List.keepIf : List elem, (elem -> Bool) -> List elem
|
||||||
pub fn list_keep_if<'a, 'ctx, 'env>(
|
pub fn list_keep_if<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
|
|
@ -114,6 +114,19 @@ mod gen_list {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn list_walk_right_empty_all_inline() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
List.walkRight [] (\a, b -> b) 0
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
i64
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn list_keep_if_empty_list_of_int() {
|
fn list_keep_if_empty_list_of_int() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
|
|
|
@ -17,6 +17,7 @@ pub enum LowLevel {
|
||||||
ListJoin,
|
ListJoin,
|
||||||
ListMap,
|
ListMap,
|
||||||
ListKeepIf,
|
ListKeepIf,
|
||||||
|
ListWalkRight,
|
||||||
NumAdd,
|
NumAdd,
|
||||||
NumSub,
|
NumSub,
|
||||||
NumMul,
|
NumMul,
|
||||||
|
|
|
@ -664,7 +664,7 @@ define_builtins! {
|
||||||
6 LIST_MAP: "map"
|
6 LIST_MAP: "map"
|
||||||
7 LIST_LEN: "len"
|
7 LIST_LEN: "len"
|
||||||
8 LIST_FOLDL: "foldl"
|
8 LIST_FOLDL: "foldl"
|
||||||
9 LIST_FOLDR: "foldr"
|
9 LIST_WALK_RIGHT: "walkRight"
|
||||||
10 LIST_CONCAT: "concat"
|
10 LIST_CONCAT: "concat"
|
||||||
11 LIST_FIRST: "first"
|
11 LIST_FIRST: "first"
|
||||||
12 LIST_SINGLE: "single"
|
12 LIST_SINGLE: "single"
|
||||||
|
|
|
@ -504,8 +504,9 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
||||||
ListAppend => arena.alloc_slice_copy(&[owned, owned]),
|
ListAppend => arena.alloc_slice_copy(&[owned, owned]),
|
||||||
ListPrepend => arena.alloc_slice_copy(&[owned, owned]),
|
ListPrepend => arena.alloc_slice_copy(&[owned, owned]),
|
||||||
ListJoin => arena.alloc_slice_copy(&[irrelevant]),
|
ListJoin => arena.alloc_slice_copy(&[irrelevant]),
|
||||||
ListMap => arena.alloc_slice_copy(&[owned, borrowed]),
|
ListMap => arena.alloc_slice_copy(&[owned, irrelevant]),
|
||||||
ListKeepIf => arena.alloc_slice_copy(&[owned, borrowed]),
|
ListKeepIf => arena.alloc_slice_copy(&[owned, irrelevant]),
|
||||||
|
ListWalkRight => arena.alloc_slice_copy(&[borrowed, irrelevant, owned]),
|
||||||
|
|
||||||
Eq | NotEq | And | Or | NumAdd | NumSub | NumMul | NumGt | NumGte | NumLt | NumLte
|
Eq | NotEq | And | Or | NumAdd | NumSub | NumMul | NumGt | NumGte | NumLt | NumLte
|
||||||
| NumDivUnchecked | NumRemUnchecked => arena.alloc_slice_copy(&[irrelevant, irrelevant]),
|
| NumDivUnchecked | NumRemUnchecked => arena.alloc_slice_copy(&[irrelevant, irrelevant]),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue