mod eval_tests { use relish::ast::{eval, lex, SymTable}; use relish::ast::{Args, Ctr, Seg, Symbol, UserFn, ValueType}; #[test] fn eval_simple() { let test_doc = "(1 2)".to_string(); let mut syms = SymTable::new(); match lex(&test_doc) { Err(e) => { println!("Lexing error: {}\n", e); assert!(false) } Ok(initial_ast) => match eval(&initial_ast, &mut syms) { Err(e) => { println!("Evaluation error: {}\n", e); assert!(false) } Ok(reduced) => { assert_eq!(reduced.to_string(), test_doc) } }, } } #[test] fn eval_embedded_lists_no_funcs() { let test_doc = "(1 (1 2 3 4 5) 5)".to_string(); let mut syms = SymTable::new(); match lex(&test_doc) { Err(e) => { println!("Lexing error: {}\n", e); assert!(false) } Ok(initial_ast) => match eval(&initial_ast, &mut syms) { Err(e) => { println!("Evaluation error: {}\n", e); assert!(false) } Ok(reduced) => { assert_eq!(reduced.to_string(), test_doc) } }, } } #[test] fn eval_function_call() { let test_doc = "('one' (echo 'unwrap_me'))".to_string(); let output = "('one' 'unwrap_me')"; let mut syms = SymTable::new(); let test_external_func: Symbol = Symbol { name: String::from("echo"), args: Args::Lazy(1), conditional_branches: false, value: ValueType::FuncForm(UserFn { arg_syms: vec!["input".to_string()], ast: Box::new(Seg::from( Box::from(Ctr::Symbol("input".to_string())), Box::from(Ctr::None), )), }), }; syms.insert(String::from("echo"), test_external_func); match lex(&test_doc) { Err(e) => { println!("Lexing error: {}\n", e); assert!(false) } Ok(initial_ast) => match eval(&initial_ast, &mut syms) { Err(e) => { println!("Evaluation error: {}\n", e); assert!(false) } Ok(reduced) => { assert_eq!(reduced.to_string(), output) } }, } } #[test] fn eval_embedded_func_calls() { let test_doc = "('one' (echo (echo 'unwrap_me')))".to_string(); let output = "('one' 'unwrap_me')"; let mut syms = SymTable::new(); let test_external_func: Symbol = Symbol { name: String::from("echo"), args: Args::Lazy(1), conditional_branches: false, value: ValueType::FuncForm(UserFn { arg_syms: vec!["input".to_string()], ast: Box::new(Seg::from( Box::from(Ctr::Symbol("input".to_string())), Box::from(Ctr::None), )), }), }; syms.insert(String::from("echo"), test_external_func); match lex(&test_doc) { Err(e) => { println!("Lexing error: {}\n", e); assert!(false) } Ok(initial_ast) => match eval(&initial_ast, &mut syms) { Err(e) => { println!("Evaluation error: {}\n", e); assert!(false) } Ok(reduced) => { assert_eq!(reduced.to_string(), output) } }, } } #[test] fn eval_bad_syms() { let test_doc = "(undefined)".to_string(); let mut syms = SymTable::new(); match lex(&test_doc) { Err(e) => { println!("Lexing error: {}\n", e); assert!(false) } Ok(initial_ast) => match eval(&initial_ast, &mut syms) { Err(e) => { assert_eq!(e, "error in call to undefined: undefined symbol: undefined") } Ok(reduced) => { println!("Eval succeeded when it shouldnt have"); println!("see: {}", reduced); assert!(false) } }, } } }