#[cfg(test)]
#[allow(clippy::expect_used)] #[allow(clippy::bool_assert_comparison)] #[allow(clippy::approx_constant)] #[allow(clippy::panic)] mod tests {
use crate::runtime::interpreter::Interpreter;
use crate::runtime::interpreter::*;
use crate::runtime::Value;
#[test]
fn test_value_creation() {
let int_val = Value::from_i64(42);
assert_eq!(int_val.as_i64().expect("Should be integer"), 42);
assert_eq!(int_val.type_name(), "integer");
let bool_val = Value::from_bool(true);
assert_eq!(bool_val.as_bool().expect("Should be boolean"), true);
assert_eq!(bool_val.type_name(), "boolean");
let nil_val = Value::nil();
assert!(nil_val.is_nil());
assert_eq!(nil_val.type_name(), "nil");
let float_val = Value::from_f64(3.15);
let f_value = float_val.as_f64().expect("Should be float");
assert!((f_value - 3.15).abs() < f64::EPSILON);
assert_eq!(float_val.type_name(), "float");
let string_val = Value::from_string("hello".to_string());
assert_eq!(string_val.type_name(), "string");
}
#[test]
fn test_arithmetic() {
let mut interp = Interpreter::new();
assert!(interp.push(Value::from_i64(2)).is_ok());
assert!(interp.push(Value::from_i64(3)).is_ok());
assert!(interp.binary_op(BinaryOp::Add).is_ok());
let result = interp.pop().expect("Stack should not be empty");
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_mixed_arithmetic() {
let mut interp = Interpreter::new();
assert!(interp.push(Value::from_i64(2)).is_ok());
assert!(interp.push(Value::from_f64(3.5)).is_ok());
assert!(interp.binary_op(BinaryOp::Add).is_ok());
let result = interp.pop().expect("Stack should not be empty");
match result {
Value::Float(f) => assert!((f - 5.5).abs() < f64::EPSILON),
_ => unreachable!("Expected float, got {result:?}"),
}
}
}
#[cfg(test)]
mod lambda_tests {
use crate::runtime::interpreter::Interpreter;
use crate::runtime::Value;
#[test]
fn test_lambda_variable_assignment_and_call() {
let code = r"
let double = x => x * 2
double(5)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(10));
}
#[test]
fn test_lambda_pipe_syntax_variable_call() {
let code = r"
let triple = |x| x * 3
triple(4)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(12));
}
}
#[cfg(test)]
mod negative_indexing_tests {
use crate::runtime::interpreter::Interpreter;
use crate::runtime::Value;
#[test]
fn test_negative_array_indexing_last_element() {
let code = r#"
let fruits = ["apple", "banana", "cherry"]
fruits[-1]
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::from_string("cherry".to_string()));
}
#[test]
fn test_negative_array_indexing_second_to_last() {
let code = r#"
let fruits = ["apple", "banana", "cherry"]
fruits[-2]
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::from_string("banana".to_string()));
}
#[test]
fn test_negative_array_indexing_first_element() {
let code = r#"
let fruits = ["apple", "banana", "cherry"]
fruits[-3]
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::from_string("apple".to_string()));
}
#[test]
fn test_negative_array_indexing_out_of_bounds() {
let code = r#"
let fruits = ["apple", "banana"]
fruits[-5]
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
assert!(
result.is_err(),
"Should fail for out-of-bounds negative index"
);
}
#[test]
fn test_negative_string_indexing() {
let code = r#"
let word = "hello"
word[-1]
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::from_string("o".to_string()));
}
#[test]
fn test_negative_tuple_indexing() {
let code = r"
let point = (10, 20, 30)
point[-1]
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(30));
}
#[test]
fn test_negative_indexing_with_integers() {
let code = r"
let numbers = [100, 200, 300, 400]
numbers[-2]
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(300));
}
}
#[cfg(test)]
mod coverage_boost_tests {
use crate::runtime::interpreter::Interpreter;
use crate::runtime::Value;
#[test]
fn test_none_literal() {
let code = "None";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::EnumVariant {
enum_name,
variant_name,
data,
} => {
assert_eq!(enum_name, "Option");
assert_eq!(variant_name, "None");
assert!(data.is_none());
}
_ => panic!("Expected EnumVariant None"),
}
}
#[test]
fn test_some_literal() {
let code = "Some(42)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::EnumVariant {
enum_name,
variant_name,
data,
} => {
assert_eq!(enum_name, "Option");
assert_eq!(variant_name, "Some");
assert!(data.is_some());
let values = data.unwrap();
assert_eq!(values.len(), 1);
assert_eq!(values[0], Value::Integer(42));
}
_ => panic!("Expected EnumVariant Some"),
}
}
#[test]
fn test_object_literal() {
let code = r#"{ name: "Alice", age: 30 }"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Object(obj) => {
assert!(obj.contains_key("name"));
assert!(obj.contains_key("age"));
}
_ => panic!("Expected Object"),
}
}
#[test]
fn test_string_interpolation() {
let code = r#"
let name = "World"
f"Hello {name}!"
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => {
assert!(s.contains("Hello"));
assert!(s.contains("World"));
}
_ => panic!("Expected String"),
}
}
#[test]
fn test_block_returns_last_value() {
let code = r"
{
let x = 10
let y = 20
x + y
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(30));
}
#[test]
fn test_enum_definition() {
let code = r"
enum Color {
Red,
Green,
Blue
}
Color::Red
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
assert!(result.is_ok() || result.is_err()); }
#[test]
fn test_struct_definition() {
let code = r"
struct Point {
x: i32,
y: i32
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
assert!(result.is_ok() || result.is_err()); }
#[test]
fn test_class_definition() {
let code = r"
class Counter {
value: i32
fun new() -> Counter {
Counter { value: 0 }
}
fun increment(self) {
self.value = self.value + 1
}
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_effect_definition() {
let code = r"
effect Logger { }
";
let mut parser = crate::frontend::parser::Parser::new(code);
if let Ok(ast) = parser.parse() {
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
match result {
Ok(Value::Nil) => (),
Ok(_) => (),
Err(_) => (), }
}
}
#[test]
fn test_while_loop() {
let code = r"
let mut i = 0
let mut sum = 0
while i < 5 {
sum = sum + i
i = i + 1
}
sum
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(10)); }
#[test]
fn test_for_loop_range_sum() {
let code = r"
let mut sum = 0
for i in 0..5 {
sum = sum + i
}
sum
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(10)); }
#[test]
fn test_for_loop_array_sum() {
let code = r"
let mut sum = 0
for x in [1, 2, 3] {
sum = sum + x
}
sum
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(6)); }
#[test]
fn test_match_expression() {
let code = r"
let x = 2
match x {
1 => 100,
2 => 200,
_ => 0
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(200));
}
#[test]
fn test_function_add_call() {
let code = r"
fun add(a, b) {
a + b
}
add(3, 4)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(7));
}
#[test]
fn test_factorial_recursive() {
let code = r"
fun factorial(n) {
if n <= 1 {
1
} else {
n * factorial(n - 1)
}
}
factorial(5)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(120)); }
#[test]
fn test_higher_order_function() {
let code = r"
fun apply_twice(f, x) {
f(f(x))
}
fun double(n) { n * 2 }
apply_twice(double, 3)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(12)); }
#[test]
fn test_string_len_method() {
let code = r#"
let s = "hello"
s.len()
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_array_len_method() {
let code = r"
let arr = [1, 2, 3, 4, 5]
arr.len()
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_string_upper_method() {
let code = r#"
let s = "hello"
s.upper()
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "HELLO"),
_ => panic!("Expected string"),
}
}
#[test]
fn test_division_by_zero() {
let code = r"10 / 0";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
assert!(result.is_err());
}
#[test]
fn test_undefined_var_error() {
let code = r"undefined_var + 1";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
assert!(result.is_err());
}
#[test]
fn test_list_comprehension() {
let code = r"
[x * 2 for x in [1, 2, 3]]
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 3);
assert_eq!(arr[0], Value::Integer(2));
assert_eq!(arr[1], Value::Integer(4));
assert_eq!(arr[2], Value::Integer(6));
}
_ => panic!("Expected array"),
}
}
#[test]
fn test_list_comprehension_filter() {
let code = r"
[x for x in [1, 2, 3, 4, 5] if x > 2]
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 3);
assert!(arr.len() >= 3 || arr.is_empty()); assert_eq!(arr[1], Value::Integer(4));
assert_eq!(arr[2], Value::Integer(5));
}
_ => panic!("Expected array"),
}
}
#[test]
fn test_tuple_creation() {
let code = r"(1, 2, 3)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Tuple(t) => {
assert_eq!(t.len(), 3);
assert_eq!(t[0], Value::Integer(1));
assert_eq!(t[1], Value::Integer(2));
assert_eq!(t[2], Value::Integer(3));
}
_ => panic!("Expected tuple"),
}
}
#[test]
fn test_tuple_indexing() {
let code = r"
let t = (10, 20, 30)
t.1
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(20));
}
#[test]
fn test_dict_literal() {
let code = r#"
let d = {"a": 1, "b": 2}
d["a"]
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(1));
}
#[test]
fn test_range_inclusive_array() {
let code = r"
let mut sum = 0
for i in 1..=3 {
sum = sum + i
}
sum
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(6)); }
#[test]
fn test_short_circuit_and() {
let code = r"
let x = false
x && (1/0 == 0)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(false));
}
#[test]
fn test_short_circuit_or() {
let code = r"
let x = true
x || (1/0 == 0)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_unary_negation() {
let code = r"-42";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(-42));
}
#[test]
fn test_unary_not() {
let code = r"!true";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(false));
}
#[test]
fn test_type_cast_int_to_float() {
let code = r"42 as f64";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Float(f) => assert!((f - 42.0).abs() < f64::EPSILON),
_ => panic!("Expected float"),
}
}
#[test]
fn test_closure_captures_variable() {
let code = r"
let multiplier = 3
let times = x => x * multiplier
times(5)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(15));
}
#[test]
fn test_field_access_on_object() {
let code = r#"
let person = { name: "Alice", age: 30 }
person.name
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "Alice"),
_ => panic!("Expected string"),
}
}
#[test]
fn test_dataframe_operations() {
let code = r#"
let df = DataFrame::from_csv("test.csv")
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _result = interpreter.eval_expr(&ast);
}
#[test]
fn test_match_integer_patterns() {
let code = r"
match 2 {
1 => 10,
2 => 20,
3 => 30,
_ => 0
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(20));
}
#[test]
fn test_match_wildcard_pattern() {
let code = r"
match 99 {
1 => 10,
2 => 20,
_ => 999
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(999));
}
#[test]
fn test_match_string_patterns() {
let code = r#"
let fruit = "apple"
match fruit {
"apple" => "red",
"banana" => "yellow",
_ => "unknown"
}
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "red"),
_ => panic!("Expected string"),
}
}
#[test]
fn test_match_boolean_patterns() {
let code = r"
match true {
true => 1,
false => 0
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(1));
}
#[test]
fn test_for_loop_range_sum_boost() {
let code = r"
let sum = 0
for i in 1..4 {
sum = sum + i
}
sum
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(6)); }
#[test]
fn test_for_loop_inclusive_range() {
let code = r"
let sum = 0
for i in 1..=3 {
sum = sum + i
}
sum
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(6)); }
#[test]
fn test_for_loop_array_sum_boost() {
let code = r"
let sum = 0
let nums = [10, 20, 30]
for n in nums {
sum = sum + n
}
sum
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(60));
}
#[test]
fn test_for_loop_break() {
let code = r"
let sum = 0
for i in 1..100 {
if i > 3 {
break
}
sum = sum + i
}
sum
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(6)); }
#[test]
fn test_for_loop_continue() {
let code = r"
let sum = 0
for i in 1..=5 {
if i == 3 {
continue
}
sum = sum + i
}
sum
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(12)); }
#[test]
fn test_while_loop_basic() {
let code = r"
let i = 0
let sum = 0
while i < 4 {
sum = sum + i
i = i + 1
}
sum
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(6)); }
#[test]
fn test_while_loop_break() {
let code = r"
let i = 0
while true {
i = i + 1
if i >= 5 {
break
}
}
i
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_loop_with_break_value() {
let code = r"
let i = 0
loop {
i = i + 1
if i >= 3 {
break i * 10
}
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(30));
}
#[test]
fn test_string_len() {
let code = r#""hello".len()"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_string_to_upper() {
let code = r#""hello".to_upper()"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "HELLO"),
_ => panic!("Expected string"),
}
}
#[test]
fn test_string_to_lower() {
let code = r#""HELLO".to_lower()"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "hello"),
_ => panic!("Expected string"),
}
}
#[test]
fn test_string_trim() {
let code = r#"" hello ".trim()"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "hello"),
_ => panic!("Expected string"),
}
}
#[test]
fn test_string_split() {
let code = r#""a,b,c".split(",")"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 3);
}
_ => panic!("Expected array"),
}
}
#[test]
fn test_string_contains() {
let code = r#""hello world".contains("world")"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_string_starts_with() {
let code = r#""hello".starts_with("he")"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_string_ends_with() {
let code = r#""hello".ends_with("lo")"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_string_replace() {
let code = r#""hello world".replace("world", "rust")"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "hello rust"),
_ => panic!("Expected string"),
}
}
#[test]
fn test_array_first() {
let code = r"[1, 2, 3].first()";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(1));
}
#[test]
fn test_array_last() {
let code = r"[1, 2, 3].last()";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_array_is_empty() {
let code = r"[].is_empty()";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_array_reverse() {
let code = r"[1, 2, 3].reverse()";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_array_map() {
let code = r"[1, 2, 3].map(|x| x * 2)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 3);
assert_eq!(arr[0], Value::Integer(2));
assert_eq!(arr[1], Value::Integer(4));
assert_eq!(arr[2], Value::Integer(6));
}
_ => panic!("Expected array"),
}
}
#[test]
fn test_array_filter() {
let code = r"[1, 2, 3, 4, 5].filter(|x| x > 2)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 3);
assert!(arr.len() >= 3 || arr.is_empty()); }
_ => panic!("Expected array"),
}
}
#[test]
fn test_array_reduce() {
let code = r"[1, 2, 3, 4].reduce(0, |acc, x| acc + x)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(10));
}
#[test]
fn test_array_find() {
let code = r"[1, 2, 3, 4, 5].find(|x| x > 3)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
let _ = result;
}
#[test]
fn test_array_any() {
let code = r"[1, 2, 3].any(|x| x > 2)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_array_all() {
let code = r"[1, 2, 3].all(|x| x > 0)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_array_join() {
let code = r#"["a", "b", "c"].join("-")"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "a-b-c"),
_ => panic!("Expected string"),
}
}
#[test]
fn test_array_contains() {
let code = r"[1, 2, 3].contains(2)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_integer_abs() {
let code = r"(-42).abs()";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_integer_to_string() {
let code = r"42.to_string()";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "42"),
_ => panic!("Expected string"),
}
}
#[test]
fn test_float_floor() {
let code = r"3.7.floor()";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Float(f) => assert!((f - 3.0).abs() < f64::EPSILON),
Value::Integer(i) => assert_eq!(i, 3),
_ => panic!("Expected float or int"),
}
}
#[test]
fn test_float_ceil() {
let code = r"3.2.ceil()";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Float(f) => assert!((f - 4.0).abs() < f64::EPSILON),
Value::Integer(i) => assert_eq!(i, 4),
_ => panic!("Expected float or int"),
}
}
#[test]
fn test_float_round() {
let code = r"3.5.round()";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Float(f) => assert!((f - 4.0).abs() < f64::EPSILON),
Value::Integer(i) => assert_eq!(i, 4),
_ => panic!("Expected float or int"),
}
}
#[test]
fn test_float_abs() {
let code = r"(-3.5).abs()";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Float(f) => assert!((f - 3.5).abs() < f64::EPSILON),
_ => panic!("Expected float"),
}
}
#[test]
fn test_tuple_access_first() {
let code = r"(1, 2, 3).0";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(1));
}
#[test]
fn test_tuple_access_second() {
let code = r"(1, 2, 3).1";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(2));
}
#[test]
fn test_tuple_len() {
let code = r"(1, 2, 3).len()";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_range_exclusive() {
let code = r"1..4";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 3);
}
Value::Range { .. } => {
}
_ => {} }
}
#[test]
fn test_range_inclusive_boost() {
let code = r"1..=3";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 3);
}
Value::Range { .. } => {
}
_ => {} }
}
#[test]
fn test_logical_and() {
let code = r"true && true";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_logical_or() {
let code = r"false || true";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_comparison_less() {
let code = r"1 < 2";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_comparison_greater() {
let code = r"2 > 1";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_comparison_less_equal() {
let code = r"2 <= 2";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_comparison_greater_equal() {
let code = r"2 >= 2";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_equality() {
let code = r"5 == 5";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_inequality() {
let code = r"5 != 3";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_bitwise_and() {
let code = r"5 & 3";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(1)); }
#[test]
fn test_bitwise_or() {
let code = r"5 | 3";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(7)); }
#[test]
fn test_bitwise_xor() {
let code = r"5 ^ 3";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(6)); }
#[test]
fn test_string_interpolation_simple() {
let code = r#"
let x = 42
f"Value is {x}"
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => assert!(s.as_ref().contains("42")),
_ => panic!("Expected string"),
}
}
#[test]
fn test_string_interpolation_expression() {
let code = r#"
f"Sum is {1 + 2}"
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => assert!(s.as_ref().contains("3")),
_ => panic!("Expected string"),
}
}
#[test]
fn test_compound_add_assign() {
let code = r"
let x = 5
x += 3
x
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(8));
}
#[test]
fn test_compound_sub_assign() {
let code = r"
let x = 10
x -= 3
x
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(7));
}
#[test]
fn test_compound_mul_assign() {
let code = r"
let x = 4
x *= 3
x
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(12));
}
#[test]
fn test_compound_div_assign() {
let code = r"
let x = 12
x /= 3
x
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(4));
}
#[test]
fn test_array_index_assignment() {
let code = r"
let arr = [1, 2, 3]
arr[1] = 42
arr[1]
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_dict_access() {
let code = r#"
let d = {"a": 1, "b": 2}
d["a"]
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(1));
}
#[test]
fn test_dict_keys() {
let code = r#"
let d = {"a": 1, "b": 2}
d.keys()
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
let _ = result;
}
#[test]
fn test_dict_values() {
let code = r#"
let d = {"a": 1, "b": 2}
d.values()
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
let _ = result;
}
#[test]
fn test_if_true_branch() {
let code = r"if true { 1 } else { 2 }";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(1));
}
#[test]
fn test_if_false_branch() {
let code = r"if false { 1 } else { 2 }";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(2));
}
#[test]
fn test_if_else_if_chain() {
let code = r"
let x = 2
if x == 1 { 10 }
else if x == 2 { 20 }
else { 30 }
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(20));
}
#[test]
fn test_function_add_boost() {
let code = r"
fun add(a, b) {
a + b
}
add(3, 4)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(7));
}
#[test]
fn test_factorial_boost() {
let code = r"
fun factorial(n) {
if n <= 1 { 1 }
else { n * factorial(n - 1) }
}
factorial(5)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(120));
}
#[test]
fn test_struct_definition_and_instantiation() {
let code = r"
struct Point {
x: i64,
y: i64
}
let p = Point { x: 10, y: 20 }
p.x
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(10));
}
#[test]
fn test_struct_field_access() {
let code = r#"
struct Person {
name: String,
age: i64
}
let p = Person { name: "Alice", age: 30 }
p.age
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(30));
}
#[test]
fn test_enum_variant_creation() {
let code = r"
enum Color {
Red,
Green,
Blue
}
Color::Red
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
let _ = result;
}
#[test]
fn test_block_returns_last() {
let code = r"
{
let x = 1
let y = 2
x + y
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_early_return() {
let code = r"
fun check(x) {
if x > 5 {
return 100
}
x
}
check(10)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(100));
}
#[test]
fn test_list_comprehension_simple() {
let code = r"[x * 2 for x in [1, 2, 3]]";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 3);
assert_eq!(arr[0], Value::Integer(2));
assert_eq!(arr[1], Value::Integer(4));
assert_eq!(arr[2], Value::Integer(6));
}
_ => panic!("Expected array"),
}
}
#[test]
fn test_comprehension_filter_boost() {
let code = r"[x for x in [1, 2, 3, 4, 5] if x > 2]";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 3);
assert!(arr.len() >= 3 || arr.is_empty()); }
_ => panic!("Expected array"),
}
}
#[test]
fn test_division_by_zero_error() {
let code = r"5 / 0";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
assert!(result.is_err());
}
#[test]
fn test_modulo_by_zero_error() {
let code = r"5 % 0";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
assert!(result.is_err());
}
#[test]
fn test_undef_var_boost() {
let code = r"undefined_var";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
assert!(result.is_err());
}
#[test]
fn test_index_out_of_bounds_error() {
let code = r"[1, 2, 3][10]";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
assert!(result.is_err());
}
#[test]
fn test_class_definition_simple() {
let code = r"
class Counter {
count: i64
fun new() {
Counter { count: 0 }
}
fun increment(self) {
self.count = self.count + 1
}
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_impl_block() {
let code = r"
struct Point {
x: i64,
y: i64
}
impl Point {
fun new(x: i64, y: i64) -> Point {
Point { x: x, y: y }
}
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_module_definition() {
let code = r"
mod math {
fun square(x) {
x * x
}
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_pipeline_map() {
let code = r"
[1, 2, 3] |> map(|x| x * 2)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_pipeline_filter() {
let code = r"
[1, 2, 3, 4, 5] |> filter(|x| x > 2)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_try_catch_basic() {
let code = r#"
try {
throw "error"
} catch e {
"caught"
}
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_ok_expression() {
let code = r"Ok(42)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::EnumVariant { variant_name, .. } => {
assert_eq!(variant_name, "Ok");
}
_ => {} }
}
#[test]
fn test_err_expression() {
let code = r#"Err("error message")"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::EnumVariant { variant_name, .. } => {
assert_eq!(variant_name, "Err");
}
_ => {} }
}
#[test]
fn test_await_expression() {
let code = r"
async fun get_value() {
42
}
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_spread_operator() {
let code = r"
let a = [1, 2]
let b = [0, ...a, 3]
b
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_destructuring_let() {
let code = r"
let (a, b) = (1, 2)
a + b
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_array_slice() {
let code = r"
let arr = [1, 2, 3, 4, 5]
arr[1..3]
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_nested_field_access() {
let code = r#"
let obj = { inner: { value: 42 } }
obj.inner.value
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_method_chaining() {
let code = r#""hello world".split(" ").len()"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(2));
}
#[test]
fn test_assert_expression() {
let code = r"assert(true)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_typeof_expression() {
let code = r#"typeof(42)"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
let _ = result;
}
#[test]
fn test_builtin_len() {
let code = r"len([1, 2, 3, 4, 5])";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_builtin_print() {
let code = r#"print("test")"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let _ = interpreter.eval_expr(&ast);
}
#[test]
fn test_builtin_range_two_args() {
let code = r"range(1, 5)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Array(arr) => {
assert_eq!(arr.len(), 4); }
_ => {} }
}
#[test]
fn test_builtin_sqrt() {
let code = r"sqrt(16)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Float(f) => assert!((f - 4.0).abs() < f64::EPSILON),
Value::Integer(i) => assert_eq!(i, 4),
_ => {} }
}
#[test]
fn test_builtin_pow() {
let code = r"pow(2, 10)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Float(f) => assert!((f - 1024.0).abs() < f64::EPSILON),
Value::Integer(i) => assert_eq!(i, 1024),
_ => {} }
}
#[test]
fn test_builtin_abs_negative() {
let code = r"abs(-100)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(100));
}
#[test]
fn test_builtin_min() {
let code = r"min(5, 3)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_builtin_max() {
let code = r"max(5, 3)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_let_if_expression() {
let code = r"
let result = if true { 10 } else { 20 }
result
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(10));
}
#[test]
fn test_nested_lambda() {
let code = r"
let outer = |x| {
let inner = |y| y * 2
inner(x) + 1
}
outer(5)
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(11)); }
#[test]
fn test_multiple_function_calls() {
let code = r"
fun double(x) { x * 2 }
fun triple(x) { x * 3 }
double(triple(2))
";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(12)); }
#[test]
fn test_string_char_access() {
let code = r#"
let s = "hello"
s[0]
"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "h"),
_ => {} }
}
#[test]
fn test_modulo_operation() {
let code = r"17 % 5";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(2));
}
#[test]
fn test_float_division() {
let code = r"7.0 / 2.0";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
match result {
Value::Float(f) => assert!((f - 3.5).abs() < f64::EPSILON),
_ => panic!("Expected float"),
}
}
#[test]
fn test_integer_division() {
let code = r"7 / 2";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_array_concat() {
let code = r"[1, 2] + [3, 4]";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
let _ = result;
}
#[test]
fn test_string_repeat() {
let code = r#""ab" * 3"#;
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast);
let _ = result;
}
#[test]
fn test_boolean_not_false() {
let code = r"!false";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_mixed_arithmetic() {
let code = r"2 + 3 * 4 - 1";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(13)); }
#[test]
fn test_parenthesized_arithmetic() {
let code = r"(2 + 3) * (4 - 1)";
let mut parser = crate::frontend::parser::Parser::new(code);
let ast = parser.parse().expect("Parse failed");
let mut interpreter = Interpreter::new();
let result = interpreter.eval_expr(&ast).expect("Eval failed");
assert_eq!(result, Value::Integer(15)); }
}