mod decl_lib_tests { use flesh::ast::{eval, lex, Ctr, SymTable}; use flesh::stdlib::static_stdlib; #[test] fn test_variable_def_and_lookup() { let doc1 = "(def test \"my test var\" 1)"; let doc2 = "test"; let result = "(1)"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); let res = *eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); assert_eq!(res.to_string(), result); } #[test] fn test_variable_def_and_lookup_list() { let doc1 = "(def test \"my test var\" (1))"; let doc2 = "test"; let result = "((1))"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); let res = *eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); assert_eq!(res.to_string(), result); } #[test] fn test_func_def_and_lookup() { let doc1 = "(def test \"my test func\" (hello) hello)"; let doc2 = "(test 1)"; let result = "1"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); let res = *eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); assert_eq!(res.to_string(), result); } #[test] fn test_variable_def_redef_and_lookup() { let doc1 = "(def test \"my test var\" 1)"; let doc2 = "(def test \"my test var\" \"2\")"; let doc3 = "(test)"; let result = "(\"2\")"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); let res = *eval(&lex(&doc3.to_string()).unwrap(), &mut syms).unwrap(); assert_eq!(res.to_string(), result); } #[cfg(not(feature = "implicit-load"))] #[test] fn test_variable_def_undef_and_lookup_fail() { let doc1 = "(def test \"my test var\" 1)"; let doc2 = "(def test)"; let doc3 = "(test)"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); let eval_result = eval(&lex(&doc3.to_string()).unwrap(), &mut syms); if let Err(s) = eval_result { assert_eq!( s.0.first().unwrap().message, "(is an undefined symbol)".to_string() ); } else { assert!(false); } } #[test] fn test_variable_def_redef_via_reference_and_lookup() { let doc1 = "(def test \"my test var\" 1)"; let doc2 = "(def ref \"references test\" (quote test))"; let doc3 = "(def ref \"my test var\" \"2\")"; let test = "(test)"; let res1 = "(1)"; let doc4 = "(def (eval ref) \"my test var\" \"2\")"; let res2 = "(\"2\")"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc3.to_string()).unwrap(), &mut syms).unwrap(); let r1 = *eval(&lex(&test.to_string()).unwrap(), &mut syms).unwrap(); assert_eq!(r1.to_string(), res1); eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc4.to_string()).unwrap(), &mut syms).unwrap(); let r2 = *eval(&lex(&test.to_string()).unwrap(), &mut syms).unwrap(); assert_eq!(r2.to_string(), res2); } #[test] fn test_variable_doc_dynamic() { let doc1 = "(def test-doc \"docs for test\" \"test tests tests test\")"; let doc2 = "(def test test-doc \"one\")"; let doc3 = "(eq? (and (eq? (get-doc (quote test)) test-doc) (eq? test \"one\")))"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); if let Ctr::Bool(b) = *eval(&lex(&doc3.to_string()).unwrap(), &mut syms).unwrap() { assert!(b); } else { assert!(false); } } #[test] fn test_func_def_no_args() { let doc1 = "(def test \"my test func\" () 1)"; let doc2 = "(test)"; let result = "1"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); eval(&lex(&doc1.to_string()).unwrap(), &mut syms).unwrap(); let res = *eval(&lex(&doc2.to_string()).unwrap(), &mut syms).unwrap(); assert_eq!(res.to_string(), result); } #[test] fn test_isset_true() { let doc1 = "(def test \"\" 1)"; let doc2 = "(set? test)"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); let def_tree = lex(&doc1.to_string()).unwrap(); let set_tree = lex(&doc2.to_string()).unwrap(); eval(&def_tree, &mut syms).unwrap(); if let Ctr::Bool(b) = *eval(&set_tree, &mut syms).unwrap() { assert!(b); } } #[test] fn test_isset_false() { let doc = "(set? test)"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); let set_tree = lex(&doc.to_string()).unwrap(); if let Ctr::Bool(b) = *eval(&set_tree, &mut syms).unwrap() { assert!(!b); } } #[test] fn test_env_doesnt_lose_elements() { let doc1 = "(def t \"\" 1)"; let doc2 = "(env)"; let doc3 = "t"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); let set_tree = lex(&doc1.to_string()).unwrap(); let env_tree = lex(&doc2.to_string()).unwrap(); let tst_tree = lex(&doc3.to_string()).unwrap(); eval(&set_tree, &mut syms).unwrap(); eval(&env_tree, &mut syms).unwrap(); eval(&tst_tree, &mut syms).unwrap(); } #[test] fn test_quote() { let document = "(quote (add 1 2))"; let result = "(add 1 2)"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); assert_eq!( *eval(&lex(&document.to_string()).unwrap(), &mut syms) .unwrap() .to_string(), result.to_string(), ); } #[test] fn test_eval() { let document = " (let ((stored-tree (quote (add 1 2)))) (eval stored-tree)))"; let result = "3"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); assert_eq!( *eval(&lex(&document.to_string()).unwrap(), &mut syms) .unwrap() .to_string(), result.to_string(), ); } #[test] fn test_eval_basic() { let document = "(eval (1 2 3))"; let result = "(1 2 3)"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); assert_eq!( *eval(&lex(&document.to_string()).unwrap(), &mut syms) .unwrap() .to_string(), result.to_string(), ); } #[test] fn test_lambda_str_equivalency_list() { let document = "(lambda (x y) (add x y))"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); assert_eq!( *eval(&lex(&document.to_string()).unwrap(), &mut syms) .unwrap() .to_string(), document.to_string(), ); } #[test] fn test_lambda_str_equivalency_no_args() { let document = "(lambda () (add 1 2))"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); assert_eq!( *eval(&lex(&document.to_string()).unwrap(), &mut syms) .unwrap() .to_string(), document.to_string(), ); } #[test] fn test_lambda_inline_call() { let document = "((lambda (x y) (add x y)) 1 2)"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); let it = *eval( &lex(&document.to_string()).unwrap(), &mut syms).unwrap(); if let Ctr::Integer(i) = it { assert_eq!(i, 3) } else { panic!() } } #[test] fn test_lambda_let_call() { let document = "(let ((adder (lambda (x y) (add x y)))) (adder 1 2))"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); let it = *eval( &lex(&document.to_string()).unwrap(), &mut syms).unwrap(); if let Ctr::Integer(i) = it { assert_eq!(i, 3) } else { panic!() } } #[test] fn test_lambda_var_bound_call() { let document = "(let (()) (def adder \"my adder\" (lambda (x y) (add x y))) (adder 1 2))"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); let it = *eval( &lex(&document.to_string()).unwrap(), &mut syms).unwrap(); if let Ctr::Integer(i) = it { assert_eq!(i, 3) } else { panic!() } } #[test] fn test_lambda_arg_call() { let document = "(let (()) (def appl \"\" (func item) (func item)) (def adder \"my adder\" (lambda (x) (add x 1))) (appl adder 2))"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); let it = *eval( &lex(&document.to_string()).unwrap(), &mut syms).unwrap(); if let Ctr::Integer(i) = it { assert_eq!(i, 3) } else { println!("bad result: {}", it); panic!() } } #[test] fn test_setget_doc_string() { let highly_inadvisable = "(set-doc (q help) \"help\")"; let document = "(get-doc (q help))"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); let _ = *eval( &lex(&highly_inadvisable.to_string()).unwrap(), &mut syms).unwrap(); let it = *eval( &lex(&document.to_string()).unwrap(), &mut syms).unwrap(); if let Ctr::String(i) = it { assert_eq!(i, "help".to_string()) } else { panic!() } } #[test] fn test_eval_quote() { let doc = "(eval (quote (add 1 1)))"; let mut syms = SymTable::new(); static_stdlib(&mut syms, |_: &String| (), || String::new()); assert_eq!( *eval(&lex(&doc.to_string()).unwrap(), &mut syms).unwrap().to_string(), 2.to_string() ) } }