diff --git a/compiler/can/src/builtins.rs b/compiler/can/src/builtins.rs index c4fcf9544f..99a369171f 100644 --- a/compiler/can/src/builtins.rs +++ b/compiler/can/src/builtins.rs @@ -34,9 +34,60 @@ pub fn builtin_defs(var_store: &VarStore) -> Vec { int_rem(var_store), int_is_odd(var_store), int_is_even(var_store), + int_is_zero(var_store), + int_is_positive(var_store), + int_is_negative(var_store), ] } +/// Int.isNegative : Int -> Bool +fn int_is_negative(var_store: &VarStore) -> Def { + use crate::expr::Expr::*; + + defn( + Symbol::INT_IS_NEGATIVE, + vec![Symbol::INT_IS_NEGATIVE_ARG], + var_store, + call( + Symbol::NUM_LT, + vec![Var(Symbol::INT_IS_NEGATIVE_ARG), Int(var_store.fresh(), 0)], + var_store, + ), + ) +} + +/// Int.isPositive : Int -> Bool +fn int_is_positive(var_store: &VarStore) -> Def { + use crate::expr::Expr::*; + + defn( + Symbol::INT_IS_POSITIVE, + vec![Symbol::INT_IS_POSITIVE_ARG], + var_store, + call( + Symbol::NUM_GT, + vec![Var(Symbol::INT_IS_POSITIVE_ARG), Int(var_store.fresh(), 0)], + var_store, + ), + ) +} + +/// Int.isZero : Int -> Bool +fn int_is_zero(var_store: &VarStore) -> Def { + use crate::expr::Expr::*; + + defn( + Symbol::INT_IS_ZERO, + vec![Symbol::INT_IS_ZERO_ARG], + var_store, + call( + Symbol::INT_EQ_I64, + vec![Var(Symbol::INT_IS_ZERO_ARG), Int(var_store.fresh(), 0)], + var_store, + ), + ) +} + /// Int.isOdd : Int -> Bool fn int_is_odd(var_store: &VarStore) -> Def { use crate::expr::Expr::*; diff --git a/compiler/gen/tests/gen_builtins.rs b/compiler/gen/tests/gen_builtins.rs index dd9b928612..c3b9f849cc 100644 --- a/compiler/gen/tests/gen_builtins.rs +++ b/compiler/gen/tests/gen_builtins.rs @@ -29,18 +29,24 @@ mod gen_builtins { #[test] fn f64_sqrt() { - assert_evals_to!("Float.sqrt 144", 12.0, f64); + with_larger_debug_stack(|| { + assert_evals_to!("Float.sqrt 144", 12.0, f64); + }) } #[test] fn f64_round() { - assert_evals_to!("Float.round 3.6", 4, i64); + with_larger_debug_stack(|| { + assert_evals_to!("Float.round 3.6", 4, i64); + }) } #[test] fn f64_abs() { - assert_evals_to!("Float.abs -4.7", 4.7, f64); - assert_evals_to!("Float.abs 5.8", 5.8, f64); + with_larger_debug_stack(|| { + assert_evals_to!("Float.abs -4.7", 4.7, f64); + assert_evals_to!("Float.abs 5.8", 5.8, f64); + }) } #[test] @@ -51,7 +57,9 @@ mod gen_builtins { #[test] fn empty_list_literal() { - assert_evals_to!("[]", &[], &'static [i64]); + with_larger_debug_stack(|| { + assert_evals_to!("[]", &[], &'static [i64]); + }) } #[test] @@ -61,9 +69,10 @@ mod gen_builtins { #[test] fn gen_if_fn() { - assert_evals_to!( - indoc!( - r#" + with_larger_debug_stack(|| { + assert_evals_to!( + indoc!( + r#" limitedNegate = \num -> if num == 1 then -1 @@ -74,10 +83,11 @@ mod gen_builtins { limitedNegate 1 "# - ), - -1, - i64 - ); + ), + -1, + i64 + ); + }) } #[test] @@ -95,15 +105,17 @@ mod gen_builtins { #[test] fn gen_add_f64() { - assert_evals_to!( - indoc!( - r#" + with_larger_debug_stack(|| { + assert_evals_to!( + indoc!( + r#" 1.1 + 2.4 + 3 "# - ), - 6.5, - f64 - ); + ), + 6.5, + f64 + ); + }) } #[test] @@ -147,15 +159,17 @@ mod gen_builtins { #[test] fn gen_add_i64() { - assert_evals_to!( - indoc!( - r#" + with_larger_debug_stack(|| { + assert_evals_to!( + indoc!( + r#" 1 + 2 + 3 "# - ), - 6, - i64 - ); + ), + 6, + i64 + ); + }) } #[test] @@ -257,6 +271,26 @@ mod gen_builtins { ); } + #[test] + fn gen_is_zero() { + assert_evals_to!("Int.isZero 0", true, bool); + assert_evals_to!("Int.isZero 1", false, bool); + } + + #[test] + fn gen_is_positive() { + assert_evals_to!("Int.isPositive 0", false, bool); + assert_evals_to!("Int.isPositive 1", true, bool); + assert_evals_to!("Int.isPositive -5", false, bool); + } + + #[test] + fn gen_is_negative() { + assert_evals_to!("Int.isNegative 0", false, bool); + assert_evals_to!("Int.isNegative 3", false, bool); + assert_evals_to!("Int.isNegative -2", false, bool); + } + #[test] fn gen_is_odd() { assert_evals_to!("Int.isOdd 4", false, bool); @@ -387,9 +421,10 @@ mod gen_builtins { } #[test] fn tail_call_elimination() { - assert_evals_to!( - indoc!( - r#" + with_larger_debug_stack(|| { + assert_evals_to!( + indoc!( + r#" sum = \n, accum -> when n is 0 -> accum @@ -397,10 +432,11 @@ mod gen_builtins { sum 1_000_000 0 "# - ), - 500000500000, - i64 - ); + ), + 500000500000, + i64 + ); + }) } #[test] fn int_negate() { @@ -425,12 +461,16 @@ mod gen_builtins { #[test] fn empty_list_len() { - assert_evals_to!("List.len []", 0, usize); + with_larger_debug_stack(|| { + assert_evals_to!("List.len []", 0, usize); + }) } #[test] fn basic_int_list_len() { - assert_evals_to!("List.len [ 12, 9, 6, 3 ]", 4, usize); + with_larger_debug_stack(|| { + assert_evals_to!("List.len [ 12, 9, 6, 3 ]", 4, usize); + }) } #[test] @@ -472,37 +512,43 @@ mod gen_builtins { #[test] fn empty_list_is_empty() { - assert_evals_to!("List.isEmpty []", true, bool); + with_larger_debug_stack(|| { + assert_evals_to!("List.isEmpty []", true, bool); + }) } #[test] fn first_int_list() { - assert_evals_to!( - indoc!( - r#" + with_larger_debug_stack(|| { + assert_evals_to!( + indoc!( + r#" when List.first [ 12, 9, 6, 3 ] is Ok val -> val Err _ -> -1 "# - ), - 12, - i64 - ); + ), + 12, + i64 + ); + }) } #[test] fn first_empty_list() { - assert_evals_to!( - indoc!( - r#" + with_larger_debug_stack(|| { + assert_evals_to!( + indoc!( + r#" when List.first [] is Ok val -> val Err _ -> -1 "# - ), - -1, - i64 - ); + ), + -1, + i64 + ); + }) } #[test] diff --git a/compiler/gen/tests/gen_primitives.rs b/compiler/gen/tests/gen_primitives.rs index 0818c0e144..8923cb24f8 100644 --- a/compiler/gen/tests/gen_primitives.rs +++ b/compiler/gen/tests/gen_primitives.rs @@ -13,7 +13,7 @@ mod helpers; #[cfg(test)] mod gen_primitives { - use crate::helpers::{can_expr, infer_expr, uniq_expr, CanExprOut}; + use crate::helpers::{can_expr, infer_expr, uniq_expr, with_larger_debug_stack, CanExprOut}; use bumpalo::Bump; use inkwell::context::Context; use inkwell::execution_engine::JitFunction; @@ -406,27 +406,30 @@ mod gen_primitives { #[test] fn gen_chained_defs() { - assert_evals_to!( - indoc!( - r#" - x = i1 - i3 = i2 - i1 = 1337 - i2 = i1 - y = 12.4 - - i3 - "# - ), - 1337, - i64 - ); + with_larger_debug_stack(|| { + assert_evals_to!( + indoc!( + r#" + x = i1 + i3 = i2 + i1 = 1337 + i2 = i1 + y = 12.4 + + i3 + "# + ), + 1337, + i64 + ); + }) } #[test] fn gen_nested_defs() { - assert_evals_to!( - indoc!( - r#" + with_larger_debug_stack(|| { + assert_evals_to!( + indoc!( + r#" x = 5 answer = @@ -457,9 +460,10 @@ mod gen_primitives { answer "# - ), - 1337, - i64 - ); + ), + 1337, + i64 + ); + }) } } diff --git a/compiler/gen/tests/gen_tags.rs b/compiler/gen/tests/gen_tags.rs index 96ae1a3477..1e04a956ca 100644 --- a/compiler/gen/tests/gen_tags.rs +++ b/compiler/gen/tests/gen_tags.rs @@ -13,7 +13,7 @@ mod helpers; #[cfg(test)] mod gen_tags { - use crate::helpers::{can_expr, infer_expr, uniq_expr, CanExprOut}; + use crate::helpers::{can_expr, infer_expr, uniq_expr, with_larger_debug_stack, CanExprOut}; use bumpalo::Bump; use inkwell::context::Context; use inkwell::execution_engine::JitFunction; @@ -213,9 +213,10 @@ mod gen_tags { #[test] fn even_odd() { - assert_evals_to!( - indoc!( - r#" + with_larger_debug_stack(|| { + assert_evals_to!( + indoc!( + r#" even = \n -> when n is 0 -> True @@ -230,10 +231,11 @@ mod gen_tags { odd 5 && even 42 "# - ), - true, - bool - ); + ), + true, + bool + ); + }) } #[test] diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index 735a43de61..3f097b6d5b 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -623,6 +623,12 @@ define_builtins! { 29 INT_IS_ODD_ARG: "isOdd#arg" 30 INT_IS_EVEN: "isEven" 31 INT_IS_EVEN_ARG: "isEven#arg" + 32 INT_IS_ZERO: "isZero" + 33 INT_IS_ZERO_ARG: "isZero#arg" + 34 INT_IS_POSITIVE: "isPositive" + 35 INT_IS_POSITIVE_ARG: "isPositive#arg" + 36 INT_IS_NEGATIVE: "isNegative" + 37 INT_IS_NEGATIVE_ARG: "isNegative#arg" } 3 FLOAT: "Float" => { 0 FLOAT_FLOAT: "Float" imported // the Float.Float type alias diff --git a/compiler/solve/tests/test_uniq_solve.rs b/compiler/solve/tests/test_uniq_solve.rs index 717c518b4d..4a81e568fb 100644 --- a/compiler/solve/tests/test_uniq_solve.rs +++ b/compiler/solve/tests/test_uniq_solve.rs @@ -116,14 +116,16 @@ mod test_uniq_solve { #[test] fn empty_list_literal() { - infer_eq( - indoc!( - r#" + with_larger_debug_stack(|| { + infer_eq( + indoc!( + r#" [] "# - ), - "Attr * (List *)", - ); + ), + "Attr * (List *)", + ); + }) } #[test]