use super::*;
#[test]
fn test_function_call() {
Tester::new_single_source_expect_ok("with literal arg", "
func add_two(u32 value) -> u32 {
return value + 2;
}
func foo() -> u32 {
return add_two(5);
}
").for_function("foo", |f| {
f.call_ok(Some(Value::UInt32(7)));
});
Tester::new_single_source_expect_ok("with variable arg", "
func add_two(u32 value) -> u32 {
value += 1;
return value + 1;
}
func foo() -> bool {
auto initial = 5;
auto result = add_two(initial);
return initial == 5 && result == 7;
}").for_function("foo", |f| {
f.call_ok(Some(Value::Bool(true)));
});
}
#[test]
fn test_recursion() {
// Single-chain
Tester::new_single_source_expect_ok("factorial", "
func horribly_slow_factorial(u32 term) -> u32 {
if (term <= 0) { return 1; }
return term * horribly_slow_factorial(term - 1);
}
func foo() -> u32 {
return horribly_slow_factorial(10);
}
").for_function("foo", |f| {
f.call_ok(Some(Value::UInt32(3628800)));
});
// Multi-chain horribleness
Tester::new_single_source_expect_ok("fibonacci", "
func horribly_slow_fibo(u32 term) -> u32 {
if (term <= 1) {
return 1;
}
return horribly_slow_fibo(term - 2) + horribly_slow_fibo(term - 1);
}
func foo() -> u32 {
return horribly_slow_fibo(10);
}").for_function("foo", |f| {
f.call_ok(Some(Value::UInt32(89)));
});
// Mutual recursion (in a contrived fashion, ofcourse)
Tester::new_single_source_expect_ok("mutual recursion", "
func collatz_even(u32 iter, u32 value) -> u32 {
value = value / 2;
if (value % 2 == 0) return collatz_even(iter + 1, value);
else return collatz_odd(iter + 1, value);
}
func collatz_odd(u32 iter, u32 value) -> u32 {
if (value <= 1) return iter;
value = 3 * value + 1;
if (value % 2 == 0) return collatz_even(iter + 1, value);
else return collatz_odd(iter + 1, value);
}
func foo() -> u32 {
return collatz_odd(1, 19);
}
").for_function("foo", |f| {
f.call_ok(Some(Value::UInt32(21)));
});
}
#[test]
fn test_empty_blocks() {
// Yes this is silly, but I managed to make this a bug before
Tester::new_single_source_expect_ok("traversing empty statements", "
func foo() -> u32 {
auto val = 128;
if (true) {}
while (false) {}
return val;
}
").for_function("foo", |f| { f.call_ok(Some(Value::UInt32(128))); });
}