#![cfg(test)] use crate::symbol_table::SymbolTable; use crate::tree_walk_eval::State; fn evaluate_input(input: &str) -> Result { let ast = crate::util::quick_ast(input); let mut symbol_table = SymbolTable::new(); symbol_table.process_ast(&ast).unwrap(); let reduced_ir = crate::reduced_ir::reduce(&ast, &symbol_table); reduced_ir.debug(&symbol_table); let mut state = State::new(); let mut outputs = state.evaluate(reduced_ir, true); outputs.pop().unwrap() } fn eval_assert(input: &str, expected: &str) { assert_eq!(evaluate_input(input), Ok(expected.to_string())); } #[test] fn test_basic_eval() { eval_assert("1 + 2", "3"); eval_assert("let mut a = 1; a = 2", "()"); eval_assert("let mut a = 1; a = a + 2; a", "3"); } #[test] fn op_eval() { eval_assert("- 13", "-13"); eval_assert("10 - 2", "8"); } #[test] fn function_eval() { eval_assert("fn oi(x) { x + 1 }; oi(4)", "5"); eval_assert("fn oi(x) { x + 1 }; oi(1+2)", "4"); } #[test] fn scopes() { let scope_ok = r#" let a = 20 fn haha() { let something = 38 let a = 10 a } haha() "#; eval_assert(scope_ok, "10"); let scope_ok = r#" let a = 20 fn queque() { let a = 10 a } a "#; eval_assert(scope_ok, "20"); } #[test] fn if_is_patterns() { let source = r#" type Option = Some(T) | None let x = Option::Some(9); if x is Option::Some(q) then { q } else { 0 }"#; eval_assert(source, "9"); let source = r#" type Option = Some(T) | None let x = Option::None; if x is Option::Some(q) then { q } else { 0 }"#; eval_assert(source, "0"); } #[test] fn basic_lambda_evaluation_1() { let source = r#" let q = \(x, y) { x * y } let x = q(5, 2) let y = \(m, n, o) { m + n + o }(1,2,3) (x, y) "#; eval_assert(source, r"(10, 6)"); } #[test] fn basic_lambda_evaluation_2() { let source = r#" fn milta() { \(x) { x + 33 } } milta()(10) "#; eval_assert(source, "43"); } #[test] fn import_all() { let source = r#" type Option = Some(T) | None import Option::* let x = Some(9); if x is Some(q) then { q } else { 0 }"#; //eval_assert(source, "9"); }