diff --git a/AUTHORS b/AUTHORS index d4b1c981c5..47eab87ee1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -47,3 +47,4 @@ Joshua Warner Luiz Carlos L. G. de Oliveira Oleksii Skidan Martin Janiczek +Eric Newbury diff --git a/compiler/builtins/src/std.rs b/compiler/builtins/src/std.rs index 1ced33cc9b..a78af7e971 100644 --- a/compiler/builtins/src/std.rs +++ b/compiler/builtins/src/std.rs @@ -979,6 +979,13 @@ pub fn types() -> MutMap { Box::new(list_type(flex(TVAR1))), ); + // dropFirst : List elem -> List elem + add_top_level_function_type!( + Symbol::LIST_DROP_FIRST, + vec![list_type(flex(TVAR1))], + Box::new(list_type(flex(TVAR1))), + ); + // swap : List elem, Nat, Nat -> List elem add_top_level_function_type!( Symbol::LIST_SWAP, diff --git a/compiler/can/src/builtins.rs b/compiler/can/src/builtins.rs index fb55cf56fa..d89fc247e7 100644 --- a/compiler/can/src/builtins.rs +++ b/compiler/can/src/builtins.rs @@ -92,6 +92,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option LIST_MAP4 => list_map4, LIST_DROP => list_drop, LIST_DROP_AT => list_drop_at, + LIST_DROP_FIRST => list_drop_first, LIST_DROP_LAST => list_drop_last, LIST_SWAP => list_swap, LIST_MAP_WITH_INDEX => list_map_with_index, @@ -2049,6 +2050,30 @@ fn list_drop_at(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } +fn list_drop_first(symbol: Symbol, var_store: &mut VarStore) -> Def { + let list_var = var_store.fresh(); + let index_var = var_store.fresh(); + let num_var = Variable::NAT; + let num_precision_var = Variable::NATURAL; + + let body = RunLowLevel { + op: LowLevel::ListDropAt, + args: vec![ + (list_var, Var(Symbol::ARG_1)), + (index_var, int(num_var, num_precision_var, 0)), + ], + ret_var: list_var, + }; + + defn( + symbol, + vec![(list_var, Symbol::ARG_1)], + var_store, + body, + list_var, + ) +} + /// List.dropLast: List elem -> List elem fn list_drop_last(symbol: Symbol, var_store: &mut VarStore) -> Def { let list_var = var_store.fresh(); diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index 79510c3700..36aa6e6675 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -1061,6 +1061,7 @@ define_builtins! { 38 LIST_MAX: "max" 39 LIST_MAX_GT: "#maxGt" 40 LIST_MAP4: "map4" + 41 LIST_DROP_FIRST: "dropFirst" } 5 RESULT: "Result" => { 0 RESULT_RESULT: "Result" imported // the Result.Result type alias diff --git a/compiler/test_gen/src/gen_list.rs b/compiler/test_gen/src/gen_list.rs index e483bc6e85..81a86804bf 100644 --- a/compiler/test_gen/src/gen_list.rs +++ b/compiler/test_gen/src/gen_list.rs @@ -267,6 +267,17 @@ fn list_drop_last_mutable() { ); } +#[test] +fn list_drop_first() { + assert_evals_to!( + "List.dropFirst [1, 2, 3]", + RocList::from_slice(&[2, 3]), + RocList + ); + assert_evals_to!("List.dropFirst []", RocList::from_slice(&[]), RocList); + assert_evals_to!("List.dropFirst [0]", RocList::from_slice(&[]), RocList); +} + #[test] fn list_swap() { assert_evals_to!("List.swap [] 0 1", RocList::from_slice(&[]), RocList);