From a9ab550c10af1a7be98750c3013d12a05a35818d Mon Sep 17 00:00:00 2001 From: Chad Stearns Date: Sat, 1 Aug 2020 22:28:09 -0400 Subject: [PATCH] List.join builtin and unification --- compiler/builtins/src/std.rs | 9 +++++++++ compiler/can/src/builtins.rs | 21 +++++++++++++++++++++ compiler/gen/src/llvm/build.rs | 11 +++++++++++ compiler/gen/tests/gen_list.rs | 6 ++++++ compiler/module/src/low_level.rs | 1 + compiler/module/src/symbol.rs | 1 + 6 files changed, 49 insertions(+) diff --git a/compiler/builtins/src/std.rs b/compiler/builtins/src/std.rs index 59f92c66a3..a3399d21ee 100644 --- a/compiler/builtins/src/std.rs +++ b/compiler/builtins/src/std.rs @@ -528,6 +528,15 @@ pub fn types() -> MutMap { ), ); + // join : List (List elem) -> List elem + add_type( + Symbol::LIST_JOIN, + SolvedType::Func( + vec![list_type(list_type(flex(TVAR1)))], + Box::new(list_type(flex(TVAR1))), + ), + ); + // single : a -> List a add_type( Symbol::LIST_SINGLE, diff --git a/compiler/can/src/builtins.rs b/compiler/can/src/builtins.rs index 2c111c8411..05fc2308a6 100644 --- a/compiler/can/src/builtins.rs +++ b/compiler/can/src/builtins.rs @@ -61,6 +61,7 @@ pub fn builtin_defs(var_store: &mut VarStore) -> MutMap { Symbol::LIST_REVERSE => list_reverse, Symbol::LIST_CONCAT => list_concat, Symbol::LIST_PREPEND => list_prepend, + Symbol::LIST_JOIN => list_join, Symbol::NUM_ADD => num_add, Symbol::NUM_SUB => num_sub, Symbol::NUM_MUL => num_mul, @@ -903,6 +904,26 @@ fn list_prepend(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } +/// List.join : List (List elem) -> List elem +fn list_join(symbol: Symbol, var_store: &mut VarStore) -> Def { + let list_var = var_store.fresh(); + let list_of_list_var = var_store.fresh(); + + let body = RunLowLevel { + op: LowLevel::ListJoin, + args: vec![(list_of_list_var, Var(Symbol::ARG_1))], + ret_var: list_var, + }; + + defn( + symbol, + vec![(list_of_list_var, Symbol::ARG_1)], + var_store, + body, + list_var, + ) +} + /// Num.rem : Int, Int -> Result Int [ DivByZero ]* fn num_rem(symbol: Symbol, var_store: &mut VarStore) -> Def { let num_var = var_store.fresh(); diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index 342abbb396..0bbc512691 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -1533,6 +1533,11 @@ fn list_push<'a, 'ctx, 'env>( ) } +/// List.join : List (List elem) -> List elem +fn list_join<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> BasicValueEnum<'ctx> { + empty_list(env) +} + /// List.prepend List elem, elem -> List elem fn list_prepend<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, @@ -1928,6 +1933,12 @@ fn run_low_level<'a, 'ctx, 'env>( list_prepend(env, original_wrapper, elem, elem_layout) } + ListJoin => { + // List.join : List (List elem) -> List elem + debug_assert_eq!(args.len(), 1); + + list_join(env) + } NumAbs | NumNeg | NumRound | NumSqrtUnchecked | NumSin | NumCos | NumToFloat => { debug_assert_eq!(args.len(), 1); diff --git a/compiler/gen/tests/gen_list.rs b/compiler/gen/tests/gen_list.rs index bcd18eef8c..ad42726063 100644 --- a/compiler/gen/tests/gen_list.rs +++ b/compiler/gen/tests/gen_list.rs @@ -98,6 +98,12 @@ mod gen_list { ); } + #[test] + fn list_join() { + assert_evals_to!("List.join []", &[], &'static [i64]); + assert_evals_to!("List.join [ [ 1 ] ]", &[1], &'static [i64]); + } + #[test] fn list_single() { assert_evals_to!("List.single 1", &[1], &'static [i64]); diff --git a/compiler/module/src/low_level.rs b/compiler/module/src/low_level.rs index ceffef2430..32f17f9284 100644 --- a/compiler/module/src/low_level.rs +++ b/compiler/module/src/low_level.rs @@ -13,6 +13,7 @@ pub enum LowLevel { ListConcat, ListAppend, ListPrepend, + ListJoin, NumAdd, NumSub, NumMul, diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index d74c522c01..15a8477c65 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -659,6 +659,7 @@ define_builtins! { 13 LIST_REPEAT: "repeat" 14 LIST_REVERSE: "reverse" 15 LIST_PREPEND: "prepend" + 16 LIST_JOIN: "join" } 5 RESULT: "Result" => { 0 RESULT_RESULT: "Result" imported // the Result.Result type alias