isZero, isPositive, isNegative

This commit is contained in:
Chad Stearns 2020-05-18 12:49:27 -04:00
parent 40cd77ec95
commit a01bdd66c5
6 changed files with 198 additions and 87 deletions

View file

@ -34,9 +34,60 @@ pub fn builtin_defs(var_store: &VarStore) -> Vec<Def> {
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::*;

View file

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

View file

@ -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
with_larger_debug_stack(|| {
assert_evals_to!(
indoc!(
r#"
x = i1
i3 = i2
i1 = 1337
i2 = i1
y = 12.4
i3
"#
),
1337,
i64
);
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
);
})
}
}

View file

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

View file

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

View file

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