mod common; use common::EvalToStr; use rusche::eval::{EvalContext, Evaluator}; fn eval_str(src: &str) -> String { Evaluator::with_builtin().eval_to_str(src) } #[test] fn test_car() { assert_eq!(eval_str("(car '(1 2))"), "1"); } #[test] fn test_cdr() { assert_eq!(eval_str("(cdr '(1 2))"), "(2)"); } #[test] fn test_define_variable() { let e = Evaluator::with_builtin(); let outer_context = e.context(); let _ = outer_context.eval_to_str("(define x 1)"); assert_eq!(outer_context.eval_to_str("x"), "1"); let _ = outer_context.eval_to_str("(set! x 2)"); assert_eq!(outer_context.eval_to_str("x"), "2"); let inner_context = EvalContext::derive_from(&outer_context); let _ = inner_context.eval_to_str("(define y 100)"); assert_eq!(inner_context.eval_to_str("y"), "100"); let _ = inner_context.eval_to_str("(set! y 200)"); assert_eq!(inner_context.eval_to_str("y"), "200"); assert_eq!(inner_context.eval_to_str("x"), "2"); assert!(outer_context.eval_to_str("y").starts_with("Err:")); } #[test] fn test_define_lambda() { let e = Evaluator::with_builtin(); let _ = e.eval_to_str("(define (do-math x y) (num-subtract (num-multiply x 2) y))"); assert_eq!(e.eval_to_str("(do-math 50 1)"), "99"); } #[test] fn test_eval() { assert_eq!(eval_str("(eval '(num-add 1 2))"), "3"); } #[test] fn test_if() { assert_eq!(eval_str("(if 't 1)"), "1"); assert_eq!(eval_str("(if 't 1 2)"), "1"); assert_eq!(eval_str("(if '() 1)"), "()"); assert_eq!(eval_str("(if '() 1 2)"), "2"); } #[test] fn test_lambda() { assert_eq!(eval_str("((lambda (x) (num-multiply x 2)) 5)"), "10"); } #[test] fn test_set() { let e = Evaluator::with_builtin(); let outer_context = e.context(); let inner_context = EvalContext::derive_from(&outer_context); let _ = outer_context.eval_to_str("(define x 1)"); assert_eq!(outer_context.eval_to_str("x"), "1"); let _ = outer_context.eval_to_str("(set! x 2)"); assert_eq!(outer_context.eval_to_str("x"), "2"); let _ = inner_context.eval_to_str("(set! x 3)"); assert_eq!(inner_context.eval_to_str("x"), "3"); assert_eq!(outer_context.eval_to_str("x"), "3"); }