#[cfg(test)] mod tests { use std::rc::Rc; use std::cell::RefCell; use crate::ast::parser::Parser; use crate::ast::compiler::binder::Binder; use crate::ast::vm::VM; use crate::ast::types::Value; use crate::ast::nodes::UntypedKind; use crate::ast::environment::Environment; use std::fs; #[test] fn test_parse_integer_constant() { let source = "123"; let mut parser = Parser::new(source).expect("Failed to create parser"); let ast = parser.parse_expression().expect("Failed to parse"); if let UntypedKind::Constant(Value::Int(val)) = ast.kind { assert_eq!(val, 123); } else { panic!("Expected Integer constant, got {:?}", ast.kind); } } #[test] fn test_parse_negative_integer() { let source = "-42"; let mut parser = Parser::new(source).expect("Failed to create parser"); let ast = parser.parse_expression().expect("Failed to parse"); if let UntypedKind::Constant(Value::Int(val)) = ast.kind { assert_eq!(val, -42); } else { panic!("Expected Integer constant, got {:?}", ast.kind); } } #[test] fn test_parse_float_constant() { let source = "123.45"; let mut parser = Parser::new(source).expect("Failed to create parser"); let ast = parser.parse_expression().expect("Failed to parse"); if let UntypedKind::Constant(Value::Float(val)) = ast.kind { assert_eq!(val, 123.45); } else { panic!("Expected Float constant, got {:?}", ast.kind); } } #[test] fn test_parse_negative_float() { let source = "-10.5"; let mut parser = Parser::new(source).expect("Failed to create parser"); let ast = parser.parse_expression().expect("Failed to parse"); if let UntypedKind::Constant(Value::Float(val)) = ast.kind { assert_eq!(val, -10.5); } else { panic!("Expected Float constant, got {:?}", ast.kind); } } #[test] fn test_closure_modification_from_source() { let source = r#" (do (def x 10) (def f (fn [] (assign x 20))) (f) x ) "#; let mut parser = Parser::new(source).expect("Failed to create parser"); let ast = parser.parse_expression().expect("Failed to parse"); let globals = Rc::new(RefCell::new(std::collections::HashMap::new())); let mut binder = Binder::new(globals.clone()); let bound_ast = binder.bind(&ast).expect("Failed to bind"); let vm_globals = Rc::new(RefCell::new(Vec::new())); let mut vm = VM::new(vm_globals); let result = vm.run(&bound_ast); match result { Ok(Value::Int(val)) => assert_eq!(val, 20, "Closure should modify outer variable"), Ok(val) => panic!("Expected Int(20), got {:?}", val), Err(e) => panic!("VM Error: {}", e), } } #[test] fn test_examples() { let entries = fs::read_dir("examples").expect("Could not read examples directory"); for entry in entries { let entry = entry.expect("Invalid entry"); let path = entry.path(); if path.extension().map_or(false, |ext| ext == "myc") { let content = fs::read_to_string(&path).expect("Could not read file"); // Find expected output tag: ;; Output: let expected_output = content.lines() .find(|line| line.starts_with(";; Output:")) .map(|line| line.replace(";; Output:", "").trim().to_string()); if let Some(expected) = expected_output { let env = Environment::new(); let result = env.run_script(&content); match result { Ok(val) => { let val_str = format!("{}", val); assert_eq!(val_str, expected, "Example {:?} failed: expected {}, got {}", path, expected, val_str); } Err(e) => panic!("Example {:?} failed with error: {}", path, e), } } } } } }