use super::*;
#[test]
fn test_gc_track() {
let mut interp = Interpreter::new();
let value = Value::Integer(42);
let _handle = interp.gc_track(value);
}
#[test]
fn test_gc_collect() {
let mut interp = Interpreter::new();
let stats = interp.gc_collect();
let _ = stats.collections;
}
#[test]
fn test_gc_stats() {
let interp = Interpreter::new();
let stats = interp.gc_stats();
let _ = stats.collections;
}
#[test]
fn test_gc_info() {
let interp = Interpreter::new();
let info = interp.gc_info();
let _ = info;
}
#[test]
fn test_gc_set_threshold() {
let mut interp = Interpreter::new();
interp.gc_set_threshold(1000);
}
#[test]
fn test_gc_set_auto_collect() {
let mut interp = Interpreter::new();
interp.gc_set_auto_collect(true);
interp.gc_set_auto_collect(false);
}
#[test]
fn test_gc_clear() {
let mut interp = Interpreter::new();
interp.gc_clear();
}
#[test]
fn test_gc_alloc_array() {
let mut interp = Interpreter::new();
let elements = vec![Value::Integer(1), Value::Integer(2), Value::Integer(3)];
let value = interp.gc_alloc_array(elements);
match value {
Value::Array(arr) => assert_eq!(arr.len(), 3),
_ => panic!("Expected Array"),
}
}
#[test]
fn test_gc_alloc_string() {
let mut interp = Interpreter::new();
let value = interp.gc_alloc_string("hello".to_string());
match value {
Value::String(s) => assert_eq!(s.as_ref(), "hello"),
_ => panic!("Expected String"),
}
}
#[test]
fn test_get_cache_stats() {
let interp = Interpreter::new();
let stats = interp.get_cache_stats();
assert!(stats.is_empty() || !stats.is_empty());
}
#[test]
fn test_clear_caches() {
let mut interp = Interpreter::new();
interp.clear_caches();
let stats = interp.get_cache_stats();
let _ = stats;
}
#[test]
fn test_get_type_feedback_stats() {
let interp = Interpreter::new();
let stats = interp.get_type_feedback_stats();
let _ = stats;
}
#[test]
fn test_get_specialization_candidates() {
let interp = Interpreter::new();
let candidates = interp.get_specialization_candidates();
assert!(candidates.is_empty() || !candidates.is_empty());
}
#[test]
fn test_clear_type_feedback() {
let mut interp = Interpreter::new();
interp.clear_type_feedback();
let stats = interp.get_type_feedback_stats();
let _ = stats;
}
#[test]
fn test_current_env() {
let interp = Interpreter::new();
let env = interp.current_env();
assert!(env.borrow().is_empty() || !env.borrow().is_empty());
}
#[test]
fn test_push_pop_scope() {
let mut interp = Interpreter::new();
interp.push_scope();
interp.set_variable_string("x".to_string(), Value::Integer(42));
interp.pop_scope();
}
#[test]
fn test_set_variable_string() {
let mut interp = Interpreter::new();
interp.set_variable_string("test_var".to_string(), Value::Integer(100));
}
#[test]
fn test_push_pop() {
let mut interp = Interpreter::new();
interp
.push(Value::Integer(42))
.expect("push should succeed");
let value = interp.pop().expect("pop should succeed");
assert_eq!(value, Value::Integer(42));
}
#[test]
fn test_peek() {
let mut interp = Interpreter::new();
interp.push(Value::Integer(1)).expect("push should succeed");
interp.push(Value::Integer(2)).expect("push should succeed");
let value = interp.peek(0).expect("peek should succeed");
assert_eq!(value, Value::Integer(2));
}
#[test]
fn test_pop_empty_stack() {
let mut interp = Interpreter::new();
let result = interp.pop();
assert!(result.is_err());
}
#[test]
fn test_peek_empty_stack() {
let interp = Interpreter::new();
let result = interp.peek(0);
assert!(result.is_err());
}
#[test]
fn test_get_global_bindings() {
let interp = Interpreter::new();
let bindings = interp.get_global_bindings();
let _ = bindings;
}
#[test]
fn test_set_global_binding() {
let mut interp = Interpreter::new();
interp.set_global_binding("my_global".to_string(), Value::Integer(999));
let bindings = interp.get_global_bindings();
assert!(bindings.contains_key("my_global"));
}
#[test]
fn test_clear_user_variables() {
let mut interp = Interpreter::new();
interp.set_variable_string("user_var".to_string(), Value::Integer(1));
interp.clear_user_variables();
}
#[test]
fn test_binary_op_add() {
let mut interp = Interpreter::new();
interp.push(Value::Integer(10)).unwrap();
interp.push(Value::Integer(20)).unwrap();
interp
.binary_op(crate::runtime::interpreter::BinaryOp::Add)
.unwrap();
let result = interp.pop().unwrap();
assert_eq!(result, Value::Integer(30));
}
#[test]
fn test_binary_op_sub() {
let mut interp = Interpreter::new();
interp.push(Value::Integer(30)).unwrap();
interp.push(Value::Integer(10)).unwrap();
interp
.binary_op(crate::runtime::interpreter::BinaryOp::Sub)
.unwrap();
let result = interp.pop().unwrap();
assert_eq!(result, Value::Integer(20));
}
#[test]
fn test_binary_op_mul() {
let mut interp = Interpreter::new();
interp.push(Value::Integer(5)).unwrap();
interp.push(Value::Integer(6)).unwrap();
interp
.binary_op(crate::runtime::interpreter::BinaryOp::Mul)
.unwrap();
let result = interp.pop().unwrap();
assert_eq!(result, Value::Integer(30));
}
#[test]
fn test_binary_op_div() {
let mut interp = Interpreter::new();
interp.push(Value::Integer(20)).unwrap();
interp.push(Value::Integer(4)).unwrap();
interp
.binary_op(crate::runtime::interpreter::BinaryOp::Div)
.unwrap();
let result = interp.pop().unwrap();
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_eval_string_simple() {
let mut interp = Interpreter::new();
let result = interp.eval_string("42");
assert!(result.is_ok());
assert_eq!(result.unwrap(), Value::Integer(42));
}
#[test]
fn test_eval_string_expression() {
let mut interp = Interpreter::new();
let result = interp.eval_string("1 + 2");
assert!(result.is_ok());
assert_eq!(result.unwrap(), Value::Integer(3));
}
#[test]
fn test_eval_string_invalid() {
let mut interp = Interpreter::new();
let result = interp.eval_string("}{][");
assert!(result.is_err());
}
#[test]
fn test_nested_let_expressions() {
let mut interp = Interpreter::new();
let inner_let = make_let("y", make_int(10), make_ident("y"));
let outer_let = make_let("x", make_int(5), inner_let);
let result = interp.eval_expr(&outer_let).expect("should succeed");
assert_eq!(result, Value::Integer(10));
}
#[test]
fn test_deeply_nested_binary() {
let mut interp = Interpreter::new();
let left = make_binary(make_int(1), AstBinaryOp::Add, make_int(2));
let right = make_binary(make_int(3), AstBinaryOp::Add, make_int(4));
let expr = make_binary(left, AstBinaryOp::Multiply, right);
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Integer(21));
}
#[test]
fn test_chained_comparisons_2() {
let mut interp = Interpreter::new();
let expr = make_binary(make_int(5), AstBinaryOp::Greater, make_int(3));
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_large_integer() {
let mut interp = Interpreter::new();
let expr = make_int(i64::MAX);
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Integer(i64::MAX));
}
#[test]
fn test_negative_integer() {
let mut interp = Interpreter::new();
let expr = make_int(-999);
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Integer(-999));
}
#[test]
fn test_zero() {
let mut interp = Interpreter::new();
let expr = make_int(0);
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Integer(0));
}
#[test]
fn test_float_precision() {
let mut interp = Interpreter::new();
let expr = make_float(3.141592653589793);
let result = interp.eval_expr(&expr).expect("should succeed");
match result {
Value::Float(f) => assert!((f - 3.141592653589793).abs() < 1e-10),
_ => panic!("Expected Float"),
}
}
#[test]
fn test_index_access_array() {
let mut interp = Interpreter::new();
let arr = make_array(vec![make_int(1), make_int(2), make_int(3)]);
let let_arr = make_let("arr", arr, make_index(make_ident("arr"), make_int(1)));
let result = interp.eval_expr(&let_arr).expect("should succeed");
assert_eq!(result, Value::Integer(2));
}
#[test]
fn test_index_access_string() {
let mut interp = Interpreter::new();
let s = make_string("hello");
let let_s = make_let("s", s, make_index(make_ident("s"), make_int(0)));
let result = interp.eval_expr(&let_s).expect("should succeed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "h"),
_ => panic!("Expected String"),
}
}
#[test]
fn test_index_access_negative() {
let mut interp = Interpreter::new();
let arr = make_array(vec![make_int(1), make_int(2), make_int(3)]);
let let_arr = make_let("arr", arr, make_index(make_ident("arr"), make_int(-1)));
let result = interp.eval_expr(&let_arr).expect("should succeed");
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_tuple_literal() {
let mut interp = Interpreter::new();
let tuple = make_tuple(vec![make_int(1), make_string("hello"), make_bool(true)]);
let result = interp.eval_expr(&tuple).expect("should succeed");
match result {
Value::Tuple(vals) => {
assert_eq!(vals.len(), 3);
assert_eq!(vals[0], Value::Integer(1));
if let Value::String(s) = &vals[1] {
assert_eq!(s.as_ref(), "hello");
} else {
panic!("Expected String");
}
assert_eq!(vals[2], Value::Bool(true));
}
_ => panic!("Expected Tuple"),
}
}
#[test]
fn test_tuple_index_cov5() {
let mut interp = Interpreter::new();
let tuple = make_tuple(vec![make_int(10), make_int(20)]);
let let_t = make_let("t", tuple, make_index(make_ident("t"), make_int(1)));
let result = interp.eval_expr(&let_t).expect("should succeed");
assert_eq!(result, Value::Integer(20));
}
#[test]
fn test_while_loop_basic() {
let mut interp = Interpreter::new();
let init = make_let(
"x",
make_int(0),
make_while(
make_binary(make_ident("x"), AstBinaryOp::Less, make_int(3)),
make_assign(
"x",
make_binary(make_ident("x"), AstBinaryOp::Add, make_int(1)),
),
),
);
let block = make_block(vec![init, make_ident("x")]);
let result = interp.eval_expr(&block);
assert!(result.is_ok());
}
#[test]
fn test_for_loop_basic() {
let mut interp = Interpreter::new();
let for_expr = make_for(
"i",
make_array(vec![make_int(1), make_int(2), make_int(3)]),
make_ident("i"),
);
let result = interp.eval_expr(&for_expr);
assert!(result.is_ok());
}
#[test]
fn test_if_without_else() {
let mut interp = Interpreter::new();
let if_expr = make_if(make_bool(true), make_int(42), None);
let result = interp.eval_expr(&if_expr).expect("should succeed");
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_if_false_without_else() {
let mut interp = Interpreter::new();
let if_expr = make_if(make_bool(false), make_int(42), None);
let result = interp.eval_expr(&if_expr).expect("should succeed");
assert_eq!(result, Value::Nil);
}
#[test]
fn test_string_concatenation() {
let mut interp = Interpreter::new();
let expr = make_binary(
make_string("Hello, "),
AstBinaryOp::Add,
make_string("World!"),
);
let result = interp.eval_expr(&expr).expect("should succeed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "Hello, World!"),
_ => panic!("Expected String"),
}
}
#[test]
fn test_string_multiply() {
let mut interp = Interpreter::new();
let expr = make_binary(make_string("ab"), AstBinaryOp::Multiply, make_int(3));
let result = interp.eval_expr(&expr).expect("should succeed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), "ababab"),
_ => panic!("Expected String"),
}
}
#[test]
fn test_array_append() {
let mut interp = Interpreter::new();
let expr = make_binary(
make_array(vec![make_int(1), make_int(2)]),
AstBinaryOp::Add,
make_array(vec![make_int(3)]),
);
let result = interp.eval_expr(&expr).expect("should succeed");
match result {
Value::Array(vals) => {
assert_eq!(vals.len(), 3);
}
_ => panic!("Expected Array"),
}
}
#[test]
fn test_mutable_let() {
let mut interp = Interpreter::new();
let init = make_let_mut("x", make_int(5), make_ident("x"));
let result = interp.eval_expr(&init).expect("should succeed");
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_compound_assign_add() {
let mut interp = Interpreter::new();
let init = make_let_mut(
"x",
make_int(5),
make_block(vec![
make_compound_assign("x", AstBinaryOp::Add, make_int(3)),
make_ident("x"),
]),
);
let result = interp.eval_expr(&init).expect("should succeed");
assert_eq!(result, Value::Integer(8));
}
#[test]
fn test_unary_not_bool() {
let mut interp = Interpreter::new();
let expr = make_unary(UnaryOp::Not, make_bool(true));
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Bool(false));
}
#[test]
fn test_unary_negate_int() {
let mut interp = Interpreter::new();
let expr = make_unary(UnaryOp::Negate, make_int(42));
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Integer(-42));
}
#[test]
fn test_division_by_zero_error() {
let mut interp = Interpreter::new();
let expr = make_binary(make_int(10), AstBinaryOp::Divide, make_int(0));
let result = interp.eval_expr(&expr);
assert!(result.is_err());
}
#[test]
fn test_modulo_by_zero_error() {
let mut interp = Interpreter::new();
let expr = make_binary(make_int(10), AstBinaryOp::Modulo, make_int(0));
let result = interp.eval_expr(&expr);
assert!(result.is_err());
}
#[test]
fn test_nested_array_access() {
let mut interp = Interpreter::new();
let arr = make_array(vec![
make_array(vec![make_int(1), make_int(2)]),
make_array(vec![make_int(3), make_int(4)]),
]);
let let_arr = make_let(
"arr",
arr,
make_index(make_index(make_ident("arr"), make_int(1)), make_int(0)),
);
let result = interp.eval_expr(&let_arr).expect("should succeed");
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_empty_array() {
let mut interp = Interpreter::new();
let arr = make_array(vec![]);
let result = interp.eval_expr(&arr).expect("should succeed");
match result {
Value::Array(vals) => assert!(vals.is_empty()),
_ => panic!("Expected Array"),
}
}
#[test]
fn test_empty_string() {
let mut interp = Interpreter::new();
let s = make_string("");
let result = interp.eval_expr(&s).expect("should succeed");
match result {
Value::String(s) => assert_eq!(s.as_ref(), ""),
_ => panic!("Expected String"),
}
}
#[test]
fn test_boolean_and_short_circuit() {
let mut interp = Interpreter::new();
let expr = make_binary(
make_bool(false),
AstBinaryOp::And,
make_binary(make_int(1), AstBinaryOp::Divide, make_int(0)),
);
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Bool(false));
}
#[test]
fn test_boolean_or_short_circuit() {
let mut interp = Interpreter::new();
let expr = make_binary(
make_bool(true),
AstBinaryOp::Or,
make_binary(make_int(1), AstBinaryOp::Divide, make_int(0)),
);
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_range_expression() {
let mut interp = Interpreter::new();
let range = make_range(make_int(0), make_int(5), false);
let result = interp.eval_expr(&range).expect("should succeed");
match result {
Value::Range {
start,
end,
inclusive,
} => {
assert_eq!(*start, Value::Integer(0));
assert_eq!(*end, Value::Integer(5));
assert!(!inclusive);
}
_ => panic!("Expected Range"),
}
}
#[test]
fn test_nil_literal() {
let mut interp = Interpreter::new();
let unit = make_unit();
let result = interp.eval_expr(&unit).expect("should succeed");
assert_eq!(result, Value::Nil);
}
#[test]
fn test_break_in_loop() {
let mut interp = Interpreter::new();
let loop_body = make_block(vec![
make_if(
make_binary(make_ident("i"), AstBinaryOp::GreaterEqual, make_int(3)),
make_break(),
None,
),
make_assign(
"i",
make_binary(make_ident("i"), AstBinaryOp::Add, make_int(1)),
),
]);
let init = make_let_mut("i", make_int(0), make_while(make_bool(true), loop_body));
let result = interp.eval_expr(&init);
assert!(result.is_ok());
}
#[test]
fn test_continue_in_loop() {
let mut interp = Interpreter::new();
let loop_body = make_block(vec![
make_if(
make_binary(make_ident("i"), AstBinaryOp::Equal, make_int(2)),
make_continue(),
None,
),
make_ident("i"),
]);
let for_expr = make_for(
"i",
make_array(vec![make_int(1), make_int(2), make_int(3)]),
loop_body,
);
let result = interp.eval_expr(&for_expr);
assert!(result.is_ok());
}
#[test]
fn test_lambda_basic() {
let mut interp = Interpreter::new();
let lambda = make_lambda_with_params(
vec!["x".to_string()],
make_binary(make_ident("x"), AstBinaryOp::Add, make_int(1)),
);
let let_f = make_let("f", lambda, make_call(make_ident("f"), vec![make_int(5)]));
let result = interp.eval_expr(&let_f).expect("should succeed");
assert_eq!(result, Value::Integer(6));
}
#[test]
fn test_lambda_closure() {
let mut interp = Interpreter::new();
let lambda = make_lambda_with_params(
vec!["x".to_string()],
make_binary(make_ident("x"), AstBinaryOp::Add, make_ident("a")),
);
let let_a = make_let(
"a",
make_int(10),
make_let("f", lambda, make_call(make_ident("f"), vec![make_int(5)])),
);
let result = interp.eval_expr(&let_a).expect("should succeed");
assert_eq!(result, Value::Integer(15));
}
#[test]
fn test_return_in_block() {
let mut interp = Interpreter::new();
let block = make_block(vec![make_return(Some(make_int(42))), make_int(100)]);
let result = interp.eval_expr(&block);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_float_division() {
let mut interp = Interpreter::new();
let expr = make_binary(make_float(10.0), AstBinaryOp::Divide, make_float(4.0));
let result = interp.eval_expr(&expr).expect("should succeed");
match result {
Value::Float(f) => assert!((f - 2.5).abs() < 0.001),
_ => panic!("Expected Float"),
}
}
#[test]
fn test_mixed_float_int_comparison() {
let mut interp = Interpreter::new();
let expr = make_binary(make_float(5.0), AstBinaryOp::Greater, make_int(3));
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_string_equality() {
let mut interp = Interpreter::new();
let expr = make_binary(
make_string("hello"),
AstBinaryOp::Equal,
make_string("hello"),
);
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_string_inequality() {
let mut interp = Interpreter::new();
let expr = make_binary(
make_string("hello"),
AstBinaryOp::NotEqual,
make_string("world"),
);
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_array_equality() {
let mut interp = Interpreter::new();
let arr1 = make_array(vec![make_int(1), make_int(2)]);
let arr2 = make_array(vec![make_int(1), make_int(2)]);
let expr = make_binary(arr1, AstBinaryOp::Equal, arr2);
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_nested_if_else() {
let mut interp = Interpreter::new();
let inner_if = make_if(make_bool(true), make_int(2), Some(make_int(3)));
let outer_if = make_if(make_bool(false), make_int(1), Some(inner_if));
let result = interp.eval_expr(&outer_if).expect("should succeed");
assert_eq!(result, Value::Integer(2));
}
#[test]
fn test_complex_arithmetic() {
let mut interp = Interpreter::new();
let add = make_binary(make_int(10), AstBinaryOp::Add, make_int(5));
let mul = make_binary(add, AstBinaryOp::Multiply, make_int(2));
let div = make_binary(make_int(6), AstBinaryOp::Divide, make_int(3));
let expr = make_binary(mul, AstBinaryOp::Subtract, div);
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Integer(28));
}
#[test]
fn test_for_with_range() {
let mut interp = Interpreter::new();
let for_expr = make_for(
"i",
make_range(make_int(0), make_int(3), false),
make_ident("i"),
);
let result = interp.eval_expr(&for_expr);
assert!(result.is_ok());
}
#[test]
fn test_nested_blocks() {
let mut interp = Interpreter::new();
let inner = make_block(vec![make_int(42)]);
let middle = make_block(vec![inner]);
let outer = make_block(vec![middle]);
let result = interp.eval_expr(&outer).expect("should succeed");
assert_eq!(result, Value::Integer(42));
}
#[test]
fn test_multiple_statements_in_block() {
let mut interp = Interpreter::new();
let block = make_let(
"x",
make_int(1),
make_let(
"y",
make_int(2),
make_binary(make_ident("x"), AstBinaryOp::Add, make_ident("y")),
),
);
let result = interp.eval_expr(&block).expect("should succeed");
assert_eq!(result, Value::Integer(3));
}
#[test]
fn test_boolean_chain() {
let mut interp = Interpreter::new();
let and1 = make_binary(make_bool(true), AstBinaryOp::And, make_bool(true));
let and2 = make_binary(and1, AstBinaryOp::And, make_bool(false));
let result = interp.eval_expr(&and2).expect("should succeed");
assert_eq!(result, Value::Bool(false));
}
#[test]
fn test_comparison_chain() {
let mut interp = Interpreter::new();
let cmp1 = make_binary(make_int(5), AstBinaryOp::Greater, make_int(3));
let cmp2 = make_binary(make_int(3), AstBinaryOp::Greater, make_int(1));
let expr = make_binary(cmp1, AstBinaryOp::And, cmp2);
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_array_of_arrays() {
let mut interp = Interpreter::new();
let arr = make_array(vec![
make_array(vec![make_int(1)]),
make_array(vec![make_int(2)]),
make_array(vec![make_int(3)]),
]);
let result = interp.eval_expr(&arr).expect("should succeed");
match result {
Value::Array(vals) => assert_eq!(vals.len(), 3),
_ => panic!("Expected Array"),
}
}
#[test]
fn test_tuple_of_different_types() {
let mut interp = Interpreter::new();
let tuple = make_tuple(vec![
make_int(1),
make_float(2.5),
make_bool(true),
make_string("test"),
]);
let result = interp.eval_expr(&tuple).expect("should succeed");
match result {
Value::Tuple(vals) => assert_eq!(vals.len(), 4),
_ => panic!("Expected Tuple"),
}
}
#[test]
fn test_unary_double_negation() {
let mut interp = Interpreter::new();
let neg1 = make_unary(UnaryOp::Negate, make_int(5));
let neg2 = make_unary(UnaryOp::Negate, neg1);
let result = interp.eval_expr(&neg2).expect("should succeed");
assert_eq!(result, Value::Integer(5));
}
#[test]
fn test_unary_double_not() {
let mut interp = Interpreter::new();
let not1 = make_unary(UnaryOp::Not, make_bool(true));
let not2 = make_unary(UnaryOp::Not, not1);
let result = interp.eval_expr(¬2).expect("should succeed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_large_array() {
let mut interp = Interpreter::new();
let elements: Vec<Expr> = (0..100).map(|i| make_int(i)).collect();
let arr = make_array(elements);
let result = interp.eval_expr(&arr).expect("should succeed");
match result {
Value::Array(vals) => assert_eq!(vals.len(), 100),
_ => panic!("Expected Array"),
}
}
#[test]
fn test_compound_subtract() {
let mut interp = Interpreter::new();
let init = make_let_mut(
"x",
make_int(10),
make_block(vec![
make_compound_assign("x", AstBinaryOp::Subtract, make_int(3)),
make_ident("x"),
]),
);
let result = interp.eval_expr(&init).expect("should succeed");
assert_eq!(result, Value::Integer(7));
}
#[test]
fn test_compound_multiply() {
let mut interp = Interpreter::new();
let init = make_let_mut(
"x",
make_int(5),
make_block(vec![
make_compound_assign("x", AstBinaryOp::Multiply, make_int(4)),
make_ident("x"),
]),
);
let result = interp.eval_expr(&init).expect("should succeed");
assert_eq!(result, Value::Integer(20));
}
#[test]
fn test_while_with_complex_condition() {
let mut interp = Interpreter::new();
let condition = make_binary(
make_binary(make_ident("x"), AstBinaryOp::Less, make_int(5)),
AstBinaryOp::And,
make_binary(make_ident("x"), AstBinaryOp::GreaterEqual, make_int(0)),
);
let init = make_let_mut(
"x",
make_int(0),
make_while(
condition,
make_assign(
"x",
make_binary(make_ident("x"), AstBinaryOp::Add, make_int(1)),
),
),
);
let result = interp.eval_expr(&init);
assert!(result.is_ok());
}
#[test]
fn test_for_empty_array() {
let mut interp = Interpreter::new();
let for_expr = make_for("i", make_array(vec![]), make_ident("i"));
let result = interp.eval_expr(&for_expr);
assert!(result.is_ok());
}
#[test]
fn test_inclusive_range_flag() {
let mut interp = Interpreter::new();
let range = make_range(make_int(1), make_int(5), true);
let result = interp.eval_expr(&range).expect("should succeed");
match result {
Value::Range { inclusive, .. } => assert!(inclusive),
_ => panic!("Expected Range"),
}
}
#[test]
fn test_string_with_special_chars() {
let mut interp = Interpreter::new();
let s = make_string("hello\\nworld\\ttab");
let result = interp.eval_expr(&s).expect("should succeed");
match result {
Value::String(val) => assert!(val.len() > 0),
_ => panic!("Expected String"),
}
}
#[test]
fn test_negative_array_index_second() {
let mut interp = Interpreter::new();
let arr = make_array(vec![make_int(1), make_int(2), make_int(3)]);
let let_arr = make_let("arr", arr, make_index(make_ident("arr"), make_int(-2)));
let result = interp.eval_expr(&let_arr).expect("should succeed");
assert_eq!(result, Value::Integer(2));
}
#[test]
fn test_float_comparison_less() {
let mut interp = Interpreter::new();
let expr = make_binary(make_float(1.5), AstBinaryOp::Less, make_float(2.5));
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_modulo_operation() {
let mut interp = Interpreter::new();
let expr = make_binary(make_int(17), AstBinaryOp::Modulo, make_int(5));
let result = interp.eval_expr(&expr).expect("should succeed");
assert_eq!(result, Value::Integer(2));
}
#[test]
fn test_nested_let_with_same_name() {
let mut interp = Interpreter::new();
let inner = make_let("x", make_int(2), make_ident("x"));
let outer = make_let("x", make_int(1), inner);
let result = interp.eval_expr(&outer).expect("should succeed");
assert_eq!(result, Value::Integer(2));
}