mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
1346 lines
28 KiB
Rust
1346 lines
28 KiB
Rust
#[macro_use]
|
|
extern crate pretty_assertions;
|
|
#[macro_use]
|
|
extern crate indoc;
|
|
|
|
extern crate bumpalo;
|
|
extern crate inkwell;
|
|
extern crate libc;
|
|
extern crate roc_gen;
|
|
|
|
#[macro_use]
|
|
mod helpers;
|
|
|
|
#[cfg(test)]
|
|
mod gen_num {
|
|
use roc_std::RocOrder;
|
|
|
|
#[test]
|
|
fn nat_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
i : Nat
|
|
i = 1
|
|
|
|
i
|
|
"#
|
|
),
|
|
1,
|
|
usize
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn i128_signed_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
i : I128
|
|
i = 128
|
|
|
|
i
|
|
"#
|
|
),
|
|
128,
|
|
i128
|
|
);
|
|
}
|
|
#[test]
|
|
fn i64_signed_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
app "test" provides [ main ] to "./platform"
|
|
|
|
main =
|
|
i : I64
|
|
i = 64
|
|
|
|
i
|
|
"#
|
|
),
|
|
64,
|
|
i64
|
|
);
|
|
}
|
|
#[test]
|
|
fn i32_signed_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
i : I32
|
|
i = 32
|
|
|
|
i
|
|
"#
|
|
),
|
|
32,
|
|
i32
|
|
);
|
|
}
|
|
#[test]
|
|
fn i16_signed_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
i : I16
|
|
i = 16
|
|
|
|
i
|
|
"#
|
|
),
|
|
16,
|
|
i16
|
|
);
|
|
}
|
|
#[test]
|
|
fn i8_signed_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
i : I8
|
|
i = 8
|
|
|
|
i
|
|
"#
|
|
),
|
|
8,
|
|
i8
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn i128_hex_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
f : I128
|
|
f = 0x123
|
|
|
|
f
|
|
"#
|
|
),
|
|
0x123,
|
|
i128
|
|
);
|
|
}
|
|
#[test]
|
|
fn i64_hex_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
f : I64
|
|
f = 0x123
|
|
|
|
f
|
|
"#
|
|
),
|
|
0x123,
|
|
i64
|
|
);
|
|
}
|
|
#[test]
|
|
fn i32_hex_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
f : I32
|
|
f = 0x123
|
|
|
|
f
|
|
"#
|
|
),
|
|
0x123,
|
|
i32
|
|
);
|
|
}
|
|
#[test]
|
|
fn i16_hex_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
f : I16
|
|
f = 0x123
|
|
|
|
f
|
|
"#
|
|
),
|
|
0x123,
|
|
i16
|
|
);
|
|
}
|
|
#[test]
|
|
fn i8_hex_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
f : I8
|
|
f = 0xA
|
|
|
|
f
|
|
"#
|
|
),
|
|
0xA,
|
|
i8
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn u128_signed_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
i : U128
|
|
i = 128
|
|
|
|
i
|
|
"#
|
|
),
|
|
128,
|
|
u128
|
|
);
|
|
}
|
|
#[test]
|
|
fn u64_signed_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
i : U64
|
|
i = 64
|
|
|
|
i
|
|
"#
|
|
),
|
|
64,
|
|
u64
|
|
);
|
|
}
|
|
#[test]
|
|
fn u32_signed_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
i : U32
|
|
i = 32
|
|
|
|
i
|
|
"#
|
|
),
|
|
32,
|
|
u32
|
|
);
|
|
}
|
|
#[test]
|
|
fn u16_signed_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
i : U16
|
|
i = 16
|
|
|
|
i
|
|
"#
|
|
),
|
|
16,
|
|
u16
|
|
);
|
|
}
|
|
#[test]
|
|
fn u8_signed_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
i : U8
|
|
i = 8
|
|
|
|
i
|
|
"#
|
|
),
|
|
8,
|
|
u8
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn u128_hex_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
f : U128
|
|
f = 0x123
|
|
|
|
f
|
|
"#
|
|
),
|
|
0x123,
|
|
i128
|
|
);
|
|
}
|
|
#[test]
|
|
fn u64_hex_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
f : U64
|
|
f = 0x123
|
|
|
|
f
|
|
"#
|
|
),
|
|
0x123,
|
|
u64
|
|
);
|
|
}
|
|
#[test]
|
|
fn u32_hex_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
f : U32
|
|
f = 0x123
|
|
|
|
f
|
|
"#
|
|
),
|
|
0x123,
|
|
u32
|
|
);
|
|
}
|
|
#[test]
|
|
fn u16_hex_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
f : U16
|
|
f = 0x123
|
|
|
|
f
|
|
"#
|
|
),
|
|
0x123,
|
|
u16
|
|
);
|
|
}
|
|
#[test]
|
|
fn u8_hex_int_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
f : U8
|
|
f = 0xA
|
|
|
|
f
|
|
"#
|
|
),
|
|
0xA,
|
|
u8
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn f64_float_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
f : F64
|
|
f = 3.6
|
|
|
|
f
|
|
"#
|
|
),
|
|
3.6,
|
|
f64
|
|
);
|
|
}
|
|
#[test]
|
|
fn f32_float_alias() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
f : F32
|
|
f = 3.6
|
|
|
|
f
|
|
"#
|
|
),
|
|
3.6,
|
|
f32
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn f64_sqrt() {
|
|
// FIXME this works with normal types, but fails when checking uniqueness types
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.sqrt 100 is
|
|
Ok val -> val
|
|
Err _ -> -1
|
|
"#
|
|
),
|
|
10.0,
|
|
f64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn f64_round_old() {
|
|
assert_evals_to!("Num.round 3.6", 4, i64);
|
|
}
|
|
|
|
#[test]
|
|
fn f64_abs() {
|
|
assert_evals_to!("Num.abs -4.7", 4.7, f64);
|
|
assert_evals_to!("Num.abs 5.8", 5.8, f64);
|
|
//assert_evals_to!("Num.abs Num.maxFloat", f64::MAX, f64);
|
|
//assert_evals_to!("Num.abs Num.minFloat", -f64::MIN, f64);
|
|
}
|
|
|
|
#[test]
|
|
fn i64_abs() {
|
|
assert_evals_to!("Num.abs -6", 6, i64);
|
|
assert_evals_to!("Num.abs 7", 7, i64);
|
|
assert_evals_to!("Num.abs 0", 0, i64);
|
|
assert_evals_to!("Num.abs -0", 0, i64);
|
|
assert_evals_to!("Num.abs -1", 1, i64);
|
|
assert_evals_to!("Num.abs 1", 1, i64);
|
|
assert_evals_to!("Num.abs 9_000_000_000_000", 9_000_000_000_000, i64);
|
|
assert_evals_to!("Num.abs -9_000_000_000_000", 9_000_000_000_000, i64);
|
|
assert_evals_to!("Num.abs Num.maxInt", i64::MAX, i64);
|
|
assert_evals_to!("Num.abs (Num.minInt + 1)", -(i64::MIN + 1), i64);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(
|
|
expected = r#"Roc failed with message: "integer absolute overflowed because its argument is the minimum value"#
|
|
)]
|
|
fn abs_min_int_overflow() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
Num.abs Num.minInt
|
|
"#
|
|
),
|
|
0,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_if_fn() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
limitedNegate = \num ->
|
|
x =
|
|
if num == 1 then
|
|
-1
|
|
else if num == -1 then
|
|
1
|
|
else
|
|
num
|
|
x
|
|
|
|
limitedNegate 1
|
|
"#
|
|
),
|
|
-1,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_float_eq() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
1.0 == 1.0
|
|
"#
|
|
),
|
|
true,
|
|
bool
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_add_f64() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
1.1 + 2.4 + 3
|
|
"#
|
|
),
|
|
6.5,
|
|
f64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_wrap_add_nums() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
add2 = \num1, num2 -> num1 + num2
|
|
|
|
add2 4 5
|
|
"#
|
|
),
|
|
9,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_div_f64() {
|
|
// FIXME this works with normal types, but fails when checking uniqueness types
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when 48 / 2 is
|
|
Ok val -> val
|
|
Err _ -> -1
|
|
"#
|
|
),
|
|
24.0,
|
|
f64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_int_eq() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
4 == 4
|
|
"#
|
|
),
|
|
true,
|
|
bool
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_int_neq() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
4 != 5
|
|
"#
|
|
),
|
|
true,
|
|
bool
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_wrap_int_neq() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
wrappedNotEq : a, a -> Bool
|
|
wrappedNotEq = \num1, num2 ->
|
|
num1 != num2
|
|
|
|
wrappedNotEq 2 3
|
|
"#
|
|
),
|
|
true,
|
|
bool
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_add_i64() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
1 + 2 + 3
|
|
"#
|
|
),
|
|
6,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_sub_f64() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
1.5 - 2.4 - 3
|
|
"#
|
|
),
|
|
-3.9,
|
|
f64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_sub_i64() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
1 - 2 - 3
|
|
"#
|
|
),
|
|
-4,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_mul_i64() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
2 * 4 * 6
|
|
"#
|
|
),
|
|
48,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_div_i64() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when 1000 // 10 is
|
|
Ok val -> val
|
|
Err _ -> -1
|
|
"#
|
|
),
|
|
100,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_div_by_zero_i64() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when 1000 // 0 is
|
|
Err DivByZero -> 99
|
|
_ -> -24
|
|
"#
|
|
),
|
|
99,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_rem_i64() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.rem 8 3 is
|
|
Ok val -> val
|
|
Err _ -> -1
|
|
"#
|
|
),
|
|
2,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_rem_div_by_zero_i64() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.rem 8 0 is
|
|
Err DivByZero -> 4
|
|
Ok _ -> -23
|
|
"#
|
|
),
|
|
4,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_is_zero_i64() {
|
|
assert_evals_to!("Num.isZero 0", true, bool);
|
|
assert_evals_to!("Num.isZero 1", false, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_is_positive_i64() {
|
|
assert_evals_to!("Num.isPositive 0", false, bool);
|
|
assert_evals_to!("Num.isPositive 1", true, bool);
|
|
assert_evals_to!("Num.isPositive -5", false, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_is_negative_i64() {
|
|
assert_evals_to!("Num.isNegative 0", false, bool);
|
|
assert_evals_to!("Num.isNegative 3", false, bool);
|
|
assert_evals_to!("Num.isNegative -2", true, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_is_positive_f64() {
|
|
assert_evals_to!("Num.isPositive 0.0", false, bool);
|
|
assert_evals_to!("Num.isPositive 4.7", true, bool);
|
|
assert_evals_to!("Num.isPositive -8.5", false, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_is_negative_f64() {
|
|
assert_evals_to!("Num.isNegative 0.0", false, bool);
|
|
assert_evals_to!("Num.isNegative 9.9", false, bool);
|
|
assert_evals_to!("Num.isNegative -4.4", true, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_is_zero_f64() {
|
|
assert_evals_to!("Num.isZero 0", true, bool);
|
|
assert_evals_to!("Num.isZero 0_0", true, bool);
|
|
assert_evals_to!("Num.isZero 0.0", true, bool);
|
|
assert_evals_to!("Num.isZero 1", false, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_is_odd() {
|
|
assert_evals_to!("Num.isOdd 4", false, bool);
|
|
assert_evals_to!("Num.isOdd 5", true, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_is_even() {
|
|
assert_evals_to!("Num.isEven 6", true, bool);
|
|
assert_evals_to!("Num.isEven 7", false, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn sin() {
|
|
assert_evals_to!("Num.sin 0", 0.0, f64);
|
|
assert_evals_to!("Num.sin 1.41421356237", 0.9877659459922529, f64);
|
|
}
|
|
|
|
#[test]
|
|
fn cos() {
|
|
assert_evals_to!("Num.cos 0", 1.0, f64);
|
|
assert_evals_to!("Num.cos 3.14159265359", -1.0, f64);
|
|
}
|
|
|
|
#[test]
|
|
fn tan() {
|
|
assert_evals_to!("Num.tan 0", 0.0, f64);
|
|
assert_evals_to!("Num.tan 1", 1.557407724654902, f64);
|
|
}
|
|
|
|
#[test]
|
|
fn bitwise_and() {
|
|
assert_evals_to!("Num.bitwiseAnd 20 20", 20, i64);
|
|
assert_evals_to!("Num.bitwiseAnd 25 10", 8, i64);
|
|
assert_evals_to!("Num.bitwiseAnd 200 0", 0, i64);
|
|
}
|
|
|
|
#[test]
|
|
fn bitwise_xor() {
|
|
assert_evals_to!("Num.bitwiseXor 20 20", 0, i64);
|
|
assert_evals_to!("Num.bitwiseXor 15 14", 1, i64);
|
|
assert_evals_to!("Num.bitwiseXor 7 15", 8, i64);
|
|
assert_evals_to!("Num.bitwiseXor 200 0", 200, i64);
|
|
}
|
|
|
|
#[test]
|
|
fn lt_i64() {
|
|
assert_evals_to!("1 < 2", true, bool);
|
|
assert_evals_to!("1 < 1", false, bool);
|
|
assert_evals_to!("2 < 1", false, bool);
|
|
assert_evals_to!("0 < 0", false, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn lte_i64() {
|
|
assert_evals_to!("1 <= 1", true, bool);
|
|
assert_evals_to!("2 <= 1", false, bool);
|
|
assert_evals_to!("1 <= 2", true, bool);
|
|
assert_evals_to!("0 <= 0", true, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn gt_i64() {
|
|
assert_evals_to!("2 > 1", true, bool);
|
|
assert_evals_to!("2 > 2", false, bool);
|
|
assert_evals_to!("1 > 1", false, bool);
|
|
assert_evals_to!("0 > 0", false, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn gte_i64() {
|
|
assert_evals_to!("1 >= 1", true, bool);
|
|
assert_evals_to!("1 >= 2", false, bool);
|
|
assert_evals_to!("2 >= 1", true, bool);
|
|
assert_evals_to!("0 >= 0", true, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn lt_f64() {
|
|
assert_evals_to!("1.1 < 1.2", true, bool);
|
|
assert_evals_to!("1.1 < 1.1", false, bool);
|
|
assert_evals_to!("1.2 < 1.1", false, bool);
|
|
assert_evals_to!("0.0 < 0.0", false, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn lte_f64() {
|
|
assert_evals_to!("1.1 <= 1.1", true, bool);
|
|
assert_evals_to!("1.2 <= 1.1", false, bool);
|
|
assert_evals_to!("1.1 <= 1.2", true, bool);
|
|
assert_evals_to!("0.0 <= 0.0", true, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn gt_f64() {
|
|
assert_evals_to!("2.2 > 1.1", true, bool);
|
|
assert_evals_to!("2.2 > 2.2", false, bool);
|
|
assert_evals_to!("1.1 > 2.2", false, bool);
|
|
assert_evals_to!("0.0 > 0.0", false, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn gte_f64() {
|
|
assert_evals_to!("1.1 >= 1.1", true, bool);
|
|
assert_evals_to!("1.1 >= 1.2", false, bool);
|
|
assert_evals_to!("1.2 >= 1.1", true, bool);
|
|
assert_evals_to!("0.0 >= 0.0", true, bool);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_order_of_arithmetic_ops() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
1 + 3 * 7 - 2
|
|
"#
|
|
),
|
|
20,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_order_of_arithmetic_ops_complex_float() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
3 - 48 * 2.0
|
|
"#
|
|
),
|
|
-93.0,
|
|
f64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn if_guard_bind_variable_false() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
wrapper = \{} ->
|
|
when 10 is
|
|
x if x == 5 -> 0
|
|
_ -> 42
|
|
|
|
wrapper {}
|
|
"#
|
|
),
|
|
42,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn if_guard_bind_variable_true() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
wrapper = \{} ->
|
|
when 10 is
|
|
x if x == 10 -> 42
|
|
_ -> 0
|
|
|
|
wrapper {}
|
|
"#
|
|
),
|
|
42,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn tail_call_elimination() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
sum = \n, accum ->
|
|
when n is
|
|
0 -> accum
|
|
_ -> sum (n - 1) (n + accum)
|
|
|
|
sum 1_000_000 0
|
|
"#
|
|
),
|
|
500000500000,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn int_negate() {
|
|
assert_evals_to!("Num.neg 123", -123, i64);
|
|
assert_evals_to!("Num.neg Num.maxInt", -i64::MAX, i64);
|
|
assert_evals_to!("Num.neg (Num.minInt + 1)", i64::MAX, i64);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(
|
|
expected = r#"Roc failed with message: "integer negation overflowed because its argument is the minimum value"#
|
|
)]
|
|
fn neg_min_int_overflow() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
Num.neg Num.minInt
|
|
"#
|
|
),
|
|
0,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_wrap_int_neg() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
wrappedNeg = \num -> -num
|
|
|
|
wrappedNeg 3
|
|
"#
|
|
),
|
|
-3,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn gen_basic_fn() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
always42 : Num.Num (Num.Integer Num.Signed64) -> Num.Num (Num.Integer Num.Signed64)
|
|
always42 = \_ -> 42
|
|
|
|
always42 5
|
|
"#
|
|
),
|
|
42,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn int_to_float() {
|
|
assert_evals_to!("Num.toFloat 0x9", 9.0, f64);
|
|
}
|
|
|
|
#[test]
|
|
fn num_to_float() {
|
|
assert_evals_to!("Num.toFloat 9", 9.0, f64);
|
|
}
|
|
|
|
#[test]
|
|
fn float_to_float() {
|
|
assert_evals_to!("Num.toFloat 0.5", 0.5, f64);
|
|
}
|
|
|
|
#[test]
|
|
fn int_compare() {
|
|
assert_evals_to!("Num.compare 0 1", RocOrder::Lt, RocOrder);
|
|
assert_evals_to!("Num.compare 1 1", RocOrder::Eq, RocOrder);
|
|
assert_evals_to!("Num.compare 1 0", RocOrder::Gt, RocOrder);
|
|
}
|
|
|
|
#[test]
|
|
fn float_compare() {
|
|
assert_evals_to!("Num.compare 0.01 3.14", RocOrder::Lt, RocOrder);
|
|
assert_evals_to!("Num.compare 3.14 3.14", RocOrder::Eq, RocOrder);
|
|
assert_evals_to!("Num.compare 3.14 0.01", RocOrder::Gt, RocOrder);
|
|
}
|
|
|
|
#[test]
|
|
fn pow() {
|
|
assert_evals_to!("Num.pow 2.0 2.0", 4.0, f64);
|
|
}
|
|
|
|
#[test]
|
|
fn ceiling() {
|
|
assert_evals_to!("Num.ceiling 1.1", 2, i64);
|
|
}
|
|
|
|
#[test]
|
|
fn floor() {
|
|
assert_evals_to!("Num.floor 1.9", 1, i64);
|
|
}
|
|
|
|
#[test]
|
|
fn pow_int() {
|
|
assert_evals_to!("Num.powInt 2 3", 8, i64);
|
|
}
|
|
|
|
#[test]
|
|
fn atan() {
|
|
assert_evals_to!("Num.atan 10", 1.4711276743037347, f64);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = r#"Roc failed with message: "integer addition overflowed!"#)]
|
|
fn int_add_overflow() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
9_223_372_036_854_775_807 + 1
|
|
"#
|
|
),
|
|
0,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn int_add_checked() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.addChecked 1 2 is
|
|
Ok v -> v
|
|
_ -> -1
|
|
"#
|
|
),
|
|
3,
|
|
i64
|
|
);
|
|
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.addChecked 9_223_372_036_854_775_807 1 is
|
|
Err Overflow -> -1
|
|
Ok v -> v
|
|
"#
|
|
),
|
|
-1,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn int_add_wrap() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
Num.addWrap 9_223_372_036_854_775_807 1
|
|
"#
|
|
),
|
|
std::i64::MIN,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn float_add_checked_pass() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.addChecked 1.0 0.0 is
|
|
Ok v -> v
|
|
Err Overflow -> -1.0
|
|
"#
|
|
),
|
|
1.0,
|
|
f64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn float_add_checked_fail() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.addChecked 1.7976931348623157e308 1.7976931348623157e308 is
|
|
Err Overflow -> -1
|
|
Ok v -> v
|
|
"#
|
|
),
|
|
-1.0,
|
|
f64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = r#"Roc failed with message: "float addition overflowed!"#)]
|
|
fn float_add_overflow() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
1.7976931348623157e308 + 1.7976931348623157e308
|
|
"#
|
|
),
|
|
0.0,
|
|
f64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn num_max_int() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
Num.maxInt
|
|
"#
|
|
),
|
|
i64::MAX,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn num_min_int() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
Num.minInt
|
|
"#
|
|
),
|
|
i64::MIN,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = r#"Roc failed with message: "integer subtraction overflowed!"#)]
|
|
fn int_sub_overflow() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
-9_223_372_036_854_775_808 - 1
|
|
"#
|
|
),
|
|
0,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn int_sub_wrap() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
Num.subWrap -9_223_372_036_854_775_808 1
|
|
"#
|
|
),
|
|
std::i64::MAX,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = r#"Roc failed with message: "float subtraction overflowed!"#)]
|
|
fn float_sub_overflow() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
-1.7976931348623157e308 - 1.7976931348623157e308
|
|
"#
|
|
),
|
|
0.0,
|
|
f64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn int_sub_checked() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.subChecked 5 2 is
|
|
Ok v -> v
|
|
_ -> -1
|
|
"#
|
|
),
|
|
3,
|
|
i64
|
|
);
|
|
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.subChecked Num.minInt 1 is
|
|
Err Overflow -> -1
|
|
Ok v -> v
|
|
"#
|
|
),
|
|
-1,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn float_sub_checked() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.subChecked 1.0 0.0 is
|
|
Ok v -> v
|
|
Err Overflow -> -1.0
|
|
"#
|
|
),
|
|
1.0,
|
|
f64
|
|
);
|
|
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.subChecked -1.7976931348623157e308 1.7976931348623157e308 is
|
|
Err Overflow -> -1
|
|
Ok v -> v
|
|
"#
|
|
),
|
|
-1.0,
|
|
f64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = r#"Roc failed with message: "integer multiplication overflowed!"#)]
|
|
fn int_positive_mul_overflow() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
9_223_372_036_854_775_807 * 2
|
|
"#
|
|
),
|
|
0,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = r#"Roc failed with message: "integer multiplication overflowed!"#)]
|
|
fn int_negative_mul_overflow() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
(-9_223_372_036_854_775_808) * 2
|
|
"#
|
|
),
|
|
0,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = r#"Roc failed with message: "float multiplication overflowed!"#)]
|
|
fn float_positive_mul_overflow() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
1.7976931348623157e308 * 2
|
|
"#
|
|
),
|
|
0.0,
|
|
f64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = r#"Roc failed with message: "float multiplication overflowed!"#)]
|
|
fn float_negative_mul_overflow() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
-1.7976931348623157e308 * 2
|
|
"#
|
|
),
|
|
0.0,
|
|
f64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn int_mul_wrap() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
Num.mulWrap Num.maxInt 2
|
|
"#
|
|
),
|
|
-2,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn int_mul_checked() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.mulChecked 20 2 is
|
|
Ok v -> v
|
|
_ -> -1
|
|
"#
|
|
),
|
|
40,
|
|
i64
|
|
);
|
|
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.mulChecked Num.maxInt 2 is
|
|
Err Overflow -> -1
|
|
Ok v -> v
|
|
"#
|
|
),
|
|
-1,
|
|
i64
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn float_mul_checked() {
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.mulChecked 20.0 2.0 is
|
|
Ok v -> v
|
|
Err Overflow -> -1.0
|
|
"#
|
|
),
|
|
40.0,
|
|
f64
|
|
);
|
|
|
|
assert_evals_to!(
|
|
indoc!(
|
|
r#"
|
|
when Num.mulChecked 1.7976931348623157e308 2 is
|
|
Err Overflow -> -1
|
|
Ok v -> v
|
|
"#
|
|
),
|
|
-1.0,
|
|
f64
|
|
);
|
|
}
|
|
}
|