From b20f64b038c636822a90966dd5822ff0359f9d5c Mon Sep 17 00:00:00 2001 From: Ava Hahn Date: Fri, 17 Feb 2023 22:10:54 -0800 Subject: [PATCH] all tests but vars tests refactored Signed-off-by: Ava Hahn --- src/lib.rs | 6 +- tests/test_eval.rs | 173 +++++++----------------------- tests/test_func.rs | 262 +++++++++++++-------------------------------- tests/test_vars.rs | 12 +-- 4 files changed, 120 insertions(+), 333 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6ec94d4..76213de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,13 +29,13 @@ mod str;*/ extern crate lazy_static; pub mod ast { -// pub use crate::eval::eval; + pub use crate::eval::eval; pub use crate::lex::lex; pub use crate::segment::{Ctr, Seg, Type}; -/* pub use crate::sym::{ + pub use crate::sym::{ SYM_TABLE, SymTable, Symbol, UserFn, ValueType, Args - };*/ + }; } /*pub mod stdlib { diff --git a/tests/test_eval.rs b/tests/test_eval.rs index 22fb64c..46a71d7 100644 --- a/tests/test_eval.rs +++ b/tests/test_eval.rs @@ -1,34 +1,26 @@ mod eval_tests { - use relish::ast::{ast_to_string, eval, lex, new_ast, FTable, VTable}; - use relish::ast::{func_declare, Args}; - use relish::ast::{Ctr, ExternalOperation, Function, Operation}; - use std::cell::RefCell; - use std::rc::Rc; + use relish::ast::{eval, lex, SYM_TABLE}; + use relish::ast::{Args, Symbol, Ctr, Seg, ValueType, UserFn}; // TODO: write generalized testing routine on top of list of inputs #[test] fn eval_singlet() { let test_doc = "(1)".to_string(); - let ft = Rc::new(RefCell::new(FTable::new())); - let vt = Rc::new(RefCell::new(VTable::new())); - - match lex(test_doc.clone()) { + match lex(&test_doc) { Err(e) => { println!("Lexing error: {}\n", e); assert!(false) } - Ok(initial_ast) => match eval(initial_ast.clone(), vt.clone(), ft.clone(), false) { + Ok(ref initial_ast) => match eval(initial_ast, true, true) { Err(e) => { println!("Evaluation error: {}\n", e); assert!(false) } Ok(reduced) => { - if let Ctr::Seg(reduced_ast) = reduced { - assert_eq!(ast_to_string(reduced_ast), test_doc) - } + assert_eq!(reduced.to_string(), test_doc) } }, } @@ -37,25 +29,21 @@ mod eval_tests { #[test] fn eval_embedded_lists_no_funcs() { let test_doc = "(1 (1 2 3 4 5) 5)".to_string(); - let ft = Rc::new(RefCell::new(FTable::new())); - let vt = Rc::new(RefCell::new(VTable::new())); - match lex(test_doc.clone()) { + match lex(&test_doc) { Err(e) => { println!("Lexing error: {}\n", e); assert!(false) } - Ok(initial_ast) => match eval(initial_ast.clone(), vt.clone(), ft.clone(), false) { + Ok(initial_ast) => match eval(&initial_ast, true, true) { Err(e) => { println!("Evaluation error: {}\n", e); assert!(false) } Ok(reduced) => { - if let Ctr::Seg(reduced_ast) = reduced { - assert_eq!(ast_to_string(reduced_ast), test_doc) - } + assert_eq!(reduced.to_string(), test_doc) } }, } @@ -63,49 +51,39 @@ mod eval_tests { #[test] fn eval_function_call() { + let mut table_handle = SYM_TABLE.lock().unwrap(); let test_doc = "('one' (echo 'unwrap_me'))".to_string(); let output = "('one' 'unwrap_me')"; - let test_external_func: Function = Function { + let test_external_func: Symbol = Symbol { name: String::from("echo"), - loose_syms: false, - eval_lazy: false, args: Args::Lazy(1), - function: Operation::External(ExternalOperation { + has_undefined_symbols: false, + value: ValueType::FuncForm( UserFn { arg_syms: vec!["input".to_string()], - ast: new_ast( - Ctr::Seg(new_ast(Ctr::Symbol("input".to_string()), Ctr::None)), - Ctr::None, - ), + ast: Box::new(Seg::from( + Box::new(Ctr::Seg(Seg::from( + Box::from(Ctr::Symbol("input".to_string())), + Box::from(Ctr::None)))), + Box::new(Ctr::None), + )), }), }; - let ft = Rc::new(RefCell::new(FTable::new())); - let vt = Rc::new(RefCell::new(VTable::new())); - if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(test_external_func))) { - print!("Error declaring external func: {}", s); - assert!(false); - } - - match lex(test_doc) { + table_handle.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.clone(), vt.clone(), ft.clone(), false) { + Ok(initial_ast) => match eval(&initial_ast, true, true) { Err(e) => { println!("Evaluation error: {}\n", e); assert!(false) } Ok(reduced) => { - if let Ctr::Seg(reduced_ast) = reduced { - let out_doc = ast_to_string(reduced_ast); - if out_doc != output { - print!("Erroneous output: {}\n", out_doc); - assert!(false) - } - } + assert_eq!(reduced.to_string(), output) } }, } @@ -113,49 +91,39 @@ mod eval_tests { #[test] fn eval_embedded_func_calls() { + let mut table_handle = SYM_TABLE.lock().unwrap(); let test_doc = "('one' (echo (echo 'unwrap_me')))".to_string(); let output = "('one' 'unwrap_me')"; - let test_external_func: Function = Function { + let test_external_func: Symbol = Symbol{ name: String::from("echo"), - loose_syms: false, - eval_lazy: false, args: Args::Lazy(1), - function: Operation::External(ExternalOperation { + has_undefined_symbols: false, + value: ValueType::FuncForm( UserFn { arg_syms: vec!["input".to_string()], - ast: new_ast( - Ctr::Seg(new_ast(Ctr::Symbol("input".to_string()), Ctr::None)), - Ctr::None, - ), + ast: Box::new(Seg::from( + Box::new(Ctr::Seg(Seg::from( + Box::from(Ctr::Symbol("input".to_string())), + Box::from(Ctr::None)))), + Box::new(Ctr::None), + )), }), }; - let ft = Rc::new(RefCell::new(FTable::new())); - let vt = Rc::new(RefCell::new(VTable::new())); - if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(test_external_func))) { - print!("Error declaring external func: {}", s); - assert!(false); - } - - match lex(test_doc) { + table_handle.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.clone(), vt.clone(), ft.clone(), false) { + Ok(initial_ast) => match eval(&initial_ast, true, true) { Err(e) => { println!("Evaluation error: {}\n", e); assert!(false) } Ok(reduced) => { - if let Ctr::Seg(reduced_ast) = reduced { - let out_doc = ast_to_string(reduced_ast); - if out_doc != output { - print!("Erroneous output: {}\n", out_doc); - assert!(false) - } - } + assert_eq!(reduced.to_string(), output) } }, } @@ -164,82 +132,13 @@ mod eval_tests { /* #[test] fn eval_bad_vars() { - let test_doc = "".to_string(); - let ft = Rc::new(RefCell::new(FTable::new())); - let vt = Rc::new(RefCell::new(VTable::new())); - - match lex(test_doc) { - Err(e) => { - println!("Lexing error: {}\n", e); - assert!(false) - }, - - Ok(initial_ast) => { - match eval(initial_ast.clone(), vt.clone(), ft.clone(), false) { - Err(e) => { - println!("Evaluation error: {}\n", e); - assert!(false) - }, - - Ok(reduced_ast) => { - // write tests here - } - } - } - } } #[test] fn eval_bad_func() { - let test_doc = "".to_string(); - let ft = Rc::new(RefCell::new(FTable::new())); - let vt = Rc::new(RefCell::new(VTable::new())); - - match lex(test_doc) { - Err(e) => { - println!("Lexing error: {}\n", e); - assert!(false) - }, - - Ok(initial_ast) => { - match eval(initial_ast.clone(), vt.clone(), ft.clone(), false) { - Err(e) => { - println!("Evaluation error: {}\n", e); - assert!(false) - }, - - Ok(reduced_ast) => { - // write tests here - } - } - } - } } #[test] fn eval_verify_all_elems_cloned() { - let test_doc = "".to_string(); - let ft = Rc::new(RefCell::new(FTable::new())); - let vt = Rc::new(RefCell::new(VTable::new())); - - match lex(test_doc) { - Err(e) => { - println!("Lexing error: {}\n", e); - assert!(false) - }, - - Ok(initial_ast) => { - match eval(initial_ast.clone(), vt.clone(), ft.clone(), false) { - Err(e) => { - println!("Evaluation error: {}\n", e); - assert!(false) - }, - - Ok(reduced_ast) => { - // write tests here - } - } - } - } }*/ } diff --git a/tests/test_func.rs b/tests/test_func.rs index 540006b..91da402 100644 --- a/tests/test_func.rs +++ b/tests/test_func.rs @@ -1,24 +1,20 @@ mod func_tests { - use relish::ast::VTable; - use relish::ast::{ - func_call, func_declare, lex, Args, ExternalOperation, FTable, Function, Operation, - }; - use relish::ast::{new_ast, Ast, Ctr, Type}; - use std::cell::RefCell; - use std::rc::Rc; + use relish::ast::lex; + use relish::ast::{SYM_TABLE, Type, UserFn}; + use relish::ast::{Args, Symbol, Ctr, Seg, ValueType}; #[test] fn decl_and_call_internal_func() { - let test_internal_func: Function = Function { + let mut table_handle = SYM_TABLE.lock().unwrap(); + let test_internal_func: Symbol = Symbol { name: String::from("test_func_in"), - loose_syms: false, - eval_lazy: false, + has_undefined_symbols: false, args: Args::Strict(vec![Type::Bool]), - function: Operation::Internal(Box::new( - |a: Ast, _b: Rc>, _c: Rc>| -> Ctr { - let inner = a.borrow(); + value: ValueType::Internal(Box::new( + |a: &Seg| -> Ctr { + let inner = a; let mut is_bool = false; - if let Ctr::Bool(_) = &inner.car { + if let Ctr::Bool(_) = *inner.car { is_bool = true; } @@ -26,25 +22,23 @@ mod func_tests { }, )), }; - let ft = Rc::new(RefCell::new(FTable::new())); - let vt = Rc::new(RefCell::new(VTable::new())); - let args = new_ast(Ctr::Bool(true), Ctr::None); - if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(test_internal_func))) { - print!("Error declaring internal func: {}", s); - assert!(false); - } + let args = Seg::from( + Box::new(Ctr::Bool(true)), + Box::new(Ctr::None) + ); - let func: Rc>; - if let Some(f) = ft.borrow().get(&"test_func_in".to_string()) { - func = f.clone(); + table_handle.insert(String::from("test_func_in"), test_internal_func); + let func: &Symbol; + if let Some(f) = table_handle.get(&"test_func_in".to_string()) { + func = f; } else { print!("failed to retrieve function!"); assert!(false); return; } - if let Ok(ret) = func_call(func, args, vt, ft) { - match ret { + if let Ok(ret) = func.call(&args) { + match *ret { Ctr::Bool(b) => assert!(b), _ => { print!("invalid return from func!"); @@ -59,39 +53,37 @@ mod func_tests { #[test] fn decl_and_call_external_func_singlet() { - match lex("((input))".to_string()) { + let mut table_handle = SYM_TABLE.lock().unwrap(); + match lex(&"((input))".to_string()) { Err(e) => panic!("{}", e), Ok(finner) => { - let test_external_func: Function = Function { + let test_external_func: Symbol = Symbol { name: String::from("echo"), - loose_syms: false, - eval_lazy: false, + has_undefined_symbols: false, args: Args::Lazy(1), - function: Operation::External(ExternalOperation { + value: ValueType::FuncForm(UserFn{ arg_syms: vec!["input".to_string()], ast: finner, }), }; - let ft = Rc::new(RefCell::new(FTable::new())); - let vt = Rc::new(RefCell::new(VTable::new())); - let args = new_ast(Ctr::String("test".to_string()), Ctr::None); - if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(test_external_func))) - { - print!("Error declaring external func: {}", s); - assert!(false); - } - let func: Rc>; - if let Some(f) = ft.borrow().get(&"echo".to_string()) { - func = f.clone(); + let args = Seg::from( + Box::new(Ctr::String("test".to_string())), + Box::new(Ctr::None) + ); + + table_handle.insert(String::from("test_func_in"), test_external_func); + let func: &Symbol; + if let Some(f) = table_handle.get(&"test_func_in".to_string()) { + func = f; } else { print!("failed to retrieve function!"); assert!(false); return; } - match func_call(func, args, vt, ft) { - Ok(ret) => match ret { + match func.call(&args) { + Ok(ret) => match *ret { Ctr::String(b) => assert!(b == "test"), _ => { print!("Invalid return from func. Got {:?}\n", ret); @@ -109,48 +101,37 @@ mod func_tests { #[test] fn decl_and_call_external_func_multi_body() { - match lex("((input) (input))".to_string()) { + let mut table_handle = SYM_TABLE.lock().unwrap(); + match lex(&"((input) (input))".to_string()) { Err(e) => panic!("{}", e), Ok(finner) => { - let test_external_func: Function = Function { + let test_external_func: Symbol = Symbol{ name: String::from("echo_2"), - loose_syms: false, - eval_lazy: false, + has_undefined_symbols: false, args: Args::Lazy(1), - function: Operation::External(ExternalOperation { + value: ValueType::FuncForm(UserFn{ arg_syms: vec!["input".to_string()], ast: finner, }), }; - let ft = Rc::new(RefCell::new(FTable::new())); - let vt = Rc::new(RefCell::new(VTable::new())); - let args = new_ast(Ctr::String("test".to_string()), Ctr::None); - if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(test_external_func))) - { - print!("Error declaring external func: {}", s); - assert!(false); - } - let func: Rc>; - if let Some(f) = ft.borrow().get(&"echo_2".to_string()) { - func = f.clone(); + let args = Seg::from( + Box::new(Ctr::String("test".to_string())), + Box::new(Ctr::None) + ); + + table_handle.insert(String::from("echo_2"), test_external_func); + let func: &Symbol; + if let Some(f) = table_handle.get(&"echo_2".to_string()) { + func = f; } else { print!("failed to retrieve function!"); assert!(false); return; } - match func_call(func, args, vt, ft) { - Ok(ret) => match ret { - Ctr::String(s) => { - assert!(s == "test"); - } - _ => { - print!("Invalid return from function {:#?}. Should have recieved single string", ret); - assert!(false); - return; - } - }, + match func.call(&args) { + Ok(ret) => assert_eq!(ret.to_string(), "(\"test\" \"test\")"), Err(e) => { print!("Call to function failed: {}\n", e); assert!(false); @@ -162,16 +143,16 @@ mod func_tests { #[test] fn decl_and_call_func_with_nested_call() { - let inner_func: Function = Function { + let mut table_handle = SYM_TABLE.lock().unwrap(); + let inner_func: Symbol = Symbol { name: String::from("test_inner"), - loose_syms: false, - eval_lazy: false, + has_undefined_symbols: false, args: Args::Strict(vec![Type::Bool]), - function: Operation::Internal(Box::new( - |a: Ast, _b: Rc>, _c: Rc>| -> Ctr { - let inner = a.borrow(); - if let Ctr::Bool(b) = &inner.car { - if *b { + value: ValueType::Internal(Box::new( + |a: &Seg| -> Ctr { + let inner = a; + if let Ctr::Bool(b) = *inner.car { + if b { Ctr::String("test".to_string()) } else { Ctr::None @@ -183,44 +164,39 @@ mod func_tests { )), }; - match lex("((test_inner true))".to_string()) { + match lex(&"((test_inner true))".to_string()) { Err(e) => panic!("{}", e), Ok(finner) => { - let outer_func: Function = Function { + let outer_func: Symbol = Symbol { name: String::from("test_outer"), - loose_syms: false, - eval_lazy: false, + has_undefined_symbols: false, args: Args::Lazy(1), - function: Operation::External(ExternalOperation { + value: ValueType::FuncForm(UserFn{ arg_syms: vec!["input".to_string()], ast: finner, }), }; - let ft = Rc::new(RefCell::new(FTable::new())); - let vt = Rc::new(RefCell::new(VTable::new())); - let args = new_ast(Ctr::Bool(true), Ctr::None); - if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(inner_func))) { - print!("Error declaring inner func: {}", s); - assert!(false); - } - if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(outer_func))) { - print!("Error declaring outer func: {}", s); - assert!(false); - } + let args = Seg::from( + Box::new(Ctr::Bool(true)), + Box::new(Ctr::None) + ); - let func: Rc>; - if let Some(f) = ft.borrow().get(&"test_outer".to_string()) { - func = f.clone(); + table_handle.insert(String::from("test_inner"), inner_func); + table_handle.insert(String::from("test_outer"), outer_func); + + let func: &Symbol; + if let Some(f) = table_handle.get(&"test_outer".to_string()) { + func = f; } else { print!("failed to retrieve function!"); assert!(false); return; } - match func_call(func, args, vt, ft) { - Ok(ret) => match ret { + match func.call(&args) { + Ok(ret) => match *ret { Ctr::String(b) => assert!(b == "test"), _ => { print!("Invalid return from func. Got {:?}\n", ret); @@ -236,92 +212,6 @@ mod func_tests { } } - /* This test removed because it would make more sense to test this functionality in eval tests - * this function tested the evaluation of a complex argument ast that could be reduced in eval - - #[test] - fn decl_and_call_func_eval_arg() { - let is_true_func: Function = Function{ - name: String::from("is_true?"), - loose_syms: false, - eval_lazy: false, - args: Args::Strict(vec![Type::Bool]), - function: Operation::Internal( - |a: Ast, _b: Rc>, _c: Rc>| -> Ctr { - let inner = a.borrow(); - if let Ctr::Bool(b) = &inner.car { - if *b { - Ctr::String("test".to_string()) - } else { - Ctr::None - } - } else { - Ctr::None - } - } - ) - }; - - let echo_func: Function = Function{ - name: String::from("echo"), - loose_syms: false, - eval_lazy: false, - args: Args::Lazy(1), - function: Operation::External( - ExternalOperation{ - arg_syms: vec!["input".to_string()], - ast: new_ast(Ctr::Symbol("input".to_string()), Ctr::None) - } - ) - }; - - let ft = Rc::new(RefCell::new(FTable::new())); - let vt = Rc::new(RefCell::new(VTable::new())); - let args = new_ast( - Ctr::Seg(new_ast( - Ctr::Symbol("is_true?".to_string()), - Ctr::Seg(new_ast( - Ctr::Bool(true), - Ctr::None)))), - Ctr::None); - - if let Some(s) = func_declare(ft.clone(), - Rc::new(RefCell::new(is_true_func))) { - print!("Error declaring inner func: {}", s); - assert!(false); - } - if let Some(s) = func_declare(ft.clone(), - Rc::new(RefCell::new(echo_func))) { - print!("Error declaring outer func: {}", s); - assert!(false); - } - - let func: Rc>; - if let Some(f) = ft.borrow().get(&"echo".to_string()) { - func = f.clone(); - } else { - print!("failed to retrieve function!"); - assert!(false); - return; - } - - match func_call(func, args, vt, ft) { - Ok(ret) => { - match ret { - Ctr::String(b) => assert!(b == "test"), - _ => { - print!("Invalid return from func. Got {:?}\n", ret); - assert!(false); - } - } - }, - Err(e) => { - print!("Call to function failed: {}\n", e); - assert!(false); - } - } - }*/ - /* // TODO: These tests need completion! #[test] diff --git a/tests/test_vars.rs b/tests/test_vars.rs index a63663b..9197e01 100644 --- a/tests/test_vars.rs +++ b/tests/test_vars.rs @@ -1,16 +1,13 @@ -mod var_lib_tests { - use relish::ast::{eval, lex, Ctr, FTable, VTable}; - use relish::stdlib::get_stdlib; - use std::cell::RefCell; - use std::rc::Rc; +/*mod var_lib_tests { + use relish::ast::{eval, lex, SYM_TABLE}; + use relish::ast::{Args, Symbol, Ctr, Seg, ValueType, UserFn}; #[test] fn test_variable_export_and_lookup() { let doc1 = "(export test 1)"; let doc2 = "(concat test)"; let result = "1"; - let vt = Rc::new(RefCell::new(VTable::new())); - let ft: Rc>; + match get_stdlib(vt.clone()) { Ok(f) => ft = f, Err(s) => { @@ -62,3 +59,4 @@ mod var_lib_tests { } } } +*/