120 lines
2.7 KiB
Rust
120 lines
2.7 KiB
Rust
use fix::value::Value;
|
|
|
|
use crate::utils::eval;
|
|
|
|
#[test_log::test]
|
|
fn non_recursive_bindings() {
|
|
assert_eq!(eval("let x = 1; y = 2; z = x + y; in z"), Value::Int(3));
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn non_recursive_multiple_bindings() {
|
|
assert_eq!(
|
|
eval("let a = 10; b = 20; c = 30; d = a + b + c; in d"),
|
|
Value::Int(60)
|
|
);
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn recursive_fibonacci() {
|
|
assert_eq!(
|
|
eval("let fib = n: if n <= 1 then 1 else fib (n - 1) + fib (n - 2); in fib 5"),
|
|
Value::Int(8)
|
|
);
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn recursive_factorial() {
|
|
assert_eq!(
|
|
eval("let factorial = n: if n == 0 then 1 else n * factorial (n - 1); in factorial 5"),
|
|
Value::Int(120)
|
|
);
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn mutual_recursion_simple() {
|
|
assert_eq!(
|
|
eval(
|
|
"let f = n: if n == 0 then 0 else g (n - 1); g = n: if n == 0 then 1 else f (n - 1); in f 5"
|
|
),
|
|
Value::Int(1)
|
|
);
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn mutual_recursion_even_odd() {
|
|
assert_eq!(
|
|
eval(
|
|
"let even = n: if n == 0 then true else odd (n - 1); odd = n: if n == 0 then false else even (n - 1); in even 4"
|
|
),
|
|
Value::Bool(true)
|
|
);
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn mixed_recursive_and_non_recursive() {
|
|
assert_eq!(
|
|
eval("let x = 1; f = n: if n == 0 then x else f (n - 1); in f 5"),
|
|
Value::Int(1)
|
|
);
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn mixed_with_multiple_non_recursive() {
|
|
assert_eq!(
|
|
eval(
|
|
"let a = 10; b = 20; sum = a + b; countdown = n: if n == 0 then sum else countdown (n - 1); in countdown 3"
|
|
),
|
|
Value::Int(30)
|
|
);
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn rec_attrset_non_recursive() {
|
|
assert_eq!(eval("rec { x = 1; y = 2; z = x + y; }.z"), Value::Int(3));
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn rec_attrset_recursive() {
|
|
assert_eq!(
|
|
eval("rec { f = n: if n == 0 then 0 else f (n - 1); }.f 10"),
|
|
Value::Int(0)
|
|
);
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn nested_let_non_recursive() {
|
|
assert_eq!(
|
|
eval("let x = 1; in let y = x + 1; z = y + 1; in z"),
|
|
Value::Int(3)
|
|
);
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn nested_let_with_recursive() {
|
|
assert_eq!(
|
|
eval("let f = n: if n == 0 then 0 else f (n - 1); in let g = m: f m; in g 5"),
|
|
Value::Int(0)
|
|
);
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn three_way_mutual_recursion() {
|
|
assert_eq!(
|
|
eval(
|
|
"let a = n: if n == 0 then 1 else b (n - 1); b = n: if n == 0 then 2 else c (n - 1); c = n: if n == 0 then 3 else a (n - 1); in a 6"
|
|
),
|
|
Value::Int(1)
|
|
);
|
|
}
|
|
|
|
#[test_log::test]
|
|
fn complex_mixed_dependencies() {
|
|
assert_eq!(
|
|
eval(
|
|
"let x = 5; y = 10; sum = x + y; fib = n: if n <= 1 then 1 else fib (n - 1) + fib (n - 2); result = sum + fib 5; in result"
|
|
),
|
|
Value::Int(23)
|
|
);
|
|
}
|