List.walkRight definition in unique, std, builtins, etc. No implementation

This commit is contained in:
Chad Stearns 2020-09-06 14:06:08 -04:00
parent e69595b794
commit 5d0ec57461
9 changed files with 82 additions and 24 deletions

View file

@ -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,

View file

@ -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(

View file

@ -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();

View file

@ -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);

View file

@ -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>,

View file

@ -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!(

View file

@ -17,6 +17,7 @@ pub enum LowLevel {
ListJoin, ListJoin,
ListMap, ListMap,
ListKeepIf, ListKeepIf,
ListWalkRight,
NumAdd, NumAdd,
NumSub, NumSub,
NumMul, NumMul,

View file

@ -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"

View file

@ -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]),