tests function now

Signed-off-by: Ava Hahn <ava@aidanis.online>
This commit is contained in:
Ava Hahn 2023-02-24 15:29:17 -08:00
parent c70cbc701d
commit 8e13b5b87f
Signed by untrusted user who does not match committer: affine
GPG key ID: 3A4645B8CF806069
2 changed files with 61 additions and 112 deletions

View file

@ -1,5 +1,5 @@
mod eval_tests { mod eval_tests {
use relish::ast::{eval, lex, SYM_TABLE}; use relish::ast::{eval, lex, SymTable};
use relish::ast::{Args, Symbol, Ctr, Seg, ValueType, UserFn}; use relish::ast::{Args, Symbol, Ctr, Seg, ValueType, UserFn};
// TODO: write generalized testing routine on top of list of inputs // TODO: write generalized testing routine on top of list of inputs
@ -7,13 +7,14 @@ mod eval_tests {
#[test] #[test]
fn eval_singlet() { fn eval_singlet() {
let test_doc = "(1)".to_string(); let test_doc = "(1)".to_string();
let mut syms = SymTable::new();
match lex(&test_doc) { match lex(&test_doc) {
Err(e) => { Err(e) => {
println!("Lexing error: {}\n", e); println!("Lexing error: {}\n", e);
assert!(false) assert!(false)
} }
Ok(ref initial_ast) => match eval(initial_ast, true, true) { Ok(ref initial_ast) => match eval(initial_ast, &mut syms) {
Err(e) => { Err(e) => {
println!("Evaluation error: {}\n", e); println!("Evaluation error: {}\n", e);
assert!(false) assert!(false)
@ -29,14 +30,14 @@ mod eval_tests {
#[test] #[test]
fn eval_embedded_lists_no_funcs() { fn eval_embedded_lists_no_funcs() {
let test_doc = "(1 (1 2 3 4 5) 5)".to_string(); let test_doc = "(1 (1 2 3 4 5) 5)".to_string();
let mut syms = SymTable::new();
match lex(&test_doc) { match lex(&test_doc) {
Err(e) => { Err(e) => {
println!("Lexing error: {}\n", e); println!("Lexing error: {}\n", e);
assert!(false) assert!(false)
} }
Ok(initial_ast) => match eval(&initial_ast, true, true) { Ok(initial_ast) => match eval(&initial_ast, &mut syms) {
Err(e) => { Err(e) => {
println!("Evaluation error: {}\n", e); println!("Evaluation error: {}\n", e);
assert!(false) assert!(false)
@ -53,13 +54,12 @@ mod eval_tests {
fn eval_function_call() { fn eval_function_call() {
let test_doc = "('one' (echo 'unwrap_me'))".to_string(); let test_doc = "('one' (echo 'unwrap_me'))".to_string();
let output = "('one' 'unwrap_me')"; let output = "('one' 'unwrap_me')";
let mut syms = SymTable::new();
{ // we want the write lock to expire before eval
let mut table_handle = SYM_TABLE.write().unwrap();
let test_external_func: Symbol = Symbol { let test_external_func: Symbol = Symbol {
name: String::from("echo"), name: String::from("echo"),
args: Args::Lazy(1), args: Args::Lazy(1),
has_undefined_symbols: false, conditional_branches: false,
value: ValueType::FuncForm( UserFn { value: ValueType::FuncForm( UserFn {
arg_syms: vec!["input".to_string()], arg_syms: vec!["input".to_string()],
ast: Box::new(Seg::from( ast: Box::new(Seg::from(
@ -71,15 +71,15 @@ mod eval_tests {
}), }),
}; };
table_handle.insert(String::from("echo"), test_external_func); syms.insert(String::from("echo"), test_external_func);
}
match lex(&test_doc) { match lex(&test_doc) {
Err(e) => { Err(e) => {
println!("Lexing error: {}\n", e); println!("Lexing error: {}\n", e);
assert!(false) assert!(false)
} }
Ok(initial_ast) => match eval(&initial_ast, true, true) { Ok(initial_ast) => match eval(&initial_ast, &mut syms) {
Err(e) => { Err(e) => {
println!("Evaluation error: {}\n", e); println!("Evaluation error: {}\n", e);
assert!(false) assert!(false)
@ -96,13 +96,12 @@ mod eval_tests {
fn eval_embedded_func_calls() { fn eval_embedded_func_calls() {
let test_doc = "('one' (echo (echo 'unwrap_me')))".to_string(); let test_doc = "('one' (echo (echo 'unwrap_me')))".to_string();
let output = "('one' 'unwrap_me')"; let output = "('one' 'unwrap_me')";
let mut syms = SymTable::new();
{
let mut table_handle = SYM_TABLE.write().unwrap();
let test_external_func: Symbol = Symbol{ let test_external_func: Symbol = Symbol{
name: String::from("echo"), name: String::from("echo"),
args: Args::Lazy(1), args: Args::Lazy(1),
has_undefined_symbols: false, conditional_branches: false,
value: ValueType::FuncForm( UserFn { value: ValueType::FuncForm( UserFn {
arg_syms: vec!["input".to_string()], arg_syms: vec!["input".to_string()],
ast: Box::new(Seg::from( ast: Box::new(Seg::from(
@ -114,15 +113,14 @@ mod eval_tests {
}), }),
}; };
table_handle.insert(String::from("echo"), test_external_func); syms.insert(String::from("echo"), test_external_func);
}
match lex(&test_doc) { match lex(&test_doc) {
Err(e) => { Err(e) => {
println!("Lexing error: {}\n", e); println!("Lexing error: {}\n", e);
assert!(false) assert!(false)
} }
Ok(initial_ast) => match eval(&initial_ast, true, true) { Ok(initial_ast) => match eval(&initial_ast, &mut syms) {
Err(e) => { Err(e) => {
println!("Evaluation error: {}\n", e); println!("Evaluation error: {}\n", e);
assert!(false) assert!(false)

View file

@ -1,16 +1,17 @@
mod func_tests { mod func_tests {
use relish::ast::lex; use relish::ast::lex;
use relish::ast::{SYM_TABLE, Type, UserFn}; use relish::ast::{SymTable, Type, UserFn};
use relish::ast::{Args, Symbol, Ctr, Seg, ValueType}; use relish::ast::{Args, Symbol, Ctr, Seg, ValueType};
#[test] #[test]
fn decl_and_call_internal_func() { fn decl_and_call_internal_func() {
let mut syms = SymTable::new();
let test_internal_func: Symbol = Symbol { let test_internal_func: Symbol = Symbol {
name: String::from("test_func_in"), name: String::from("test_func_in"),
has_undefined_symbols: false, conditional_branches: false,
args: Args::Strict(vec![Type::Bool]), args: Args::Strict(vec![Type::Bool]),
value: ValueType::Internal(Box::new( value: ValueType::Internal(Box::new(
|a: &Seg| -> Ctr { |a: &Seg, _: &mut SymTable| -> Ctr {
let inner = a; let inner = a;
let mut is_bool = false; let mut is_bool = false;
if let Ctr::Bool(_) = *inner.car { if let Ctr::Bool(_) = *inner.car {
@ -25,22 +26,9 @@ mod func_tests {
Box::new(Ctr::None) Box::new(Ctr::None)
); );
{ syms.insert(String::from("test_func_in"), test_internal_func);
let mut table_handle = SYM_TABLE.write().unwrap();
table_handle.insert(String::from("test_func_in"), test_internal_func);
}
let table_handle = SYM_TABLE.read().unwrap(); if let Ok(ret) = syms.call_symbol(&"test_func_in".to_string(), &args, true) {
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(&args) {
match *ret { match *ret {
Ctr::Bool(b) => assert!(b), Ctr::Bool(b) => assert!(b),
_ => { _ => {
@ -56,12 +44,13 @@ mod func_tests {
#[test] #[test]
fn decl_and_call_external_func_singlet() { fn decl_and_call_external_func_singlet() {
let mut syms = SymTable::new();
match lex(&"((input))".to_string()) { match lex(&"((input))".to_string()) {
Err(e) => panic!("{}", e), Err(e) => panic!("{}", e),
Ok(finner) => { Ok(finner) => {
let test_external_func: Symbol = Symbol { let test_external_func: Symbol = Symbol {
name: String::from("echo"), name: String::from("echo"),
has_undefined_symbols: false, conditional_branches: false,
args: Args::Lazy(1), args: Args::Lazy(1),
value: ValueType::FuncForm(UserFn{ value: ValueType::FuncForm(UserFn{
arg_syms: vec!["input".to_string()], arg_syms: vec!["input".to_string()],
@ -74,22 +63,9 @@ mod func_tests {
Box::new(Ctr::None) Box::new(Ctr::None)
); );
{ syms.insert(String::from("test_func_in"), test_external_func);
let mut table_handle = SYM_TABLE.write().unwrap();
table_handle.insert(String::from("test_func_in"), test_external_func);
}
let table_handle = SYM_TABLE.read().unwrap(); match syms.call_symbol(&"test_func_in".to_string(), &args, true) {
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(&args) {
Ok(ret) => match *ret { Ok(ret) => match *ret {
Ctr::String(b) => assert!(b == "test"), Ctr::String(b) => assert!(b == "test"),
_ => { _ => {
@ -108,12 +84,13 @@ mod func_tests {
#[test] #[test]
fn decl_and_call_external_func_multi_body() { fn decl_and_call_external_func_multi_body() {
let mut syms = SymTable::new();
match lex(&"((input) (input))".to_string()) { match lex(&"((input) (input))".to_string()) {
Err(e) => panic!("{}", e), Err(e) => panic!("{}", e),
Ok(finner) => { Ok(finner) => {
let test_external_func: Symbol = Symbol{ let test_external_func: Symbol = Symbol{
name: String::from("echo_2"), name: String::from("echo_2"),
has_undefined_symbols: false, conditional_branches: false,
args: Args::Lazy(1), args: Args::Lazy(1),
value: ValueType::FuncForm(UserFn{ value: ValueType::FuncForm(UserFn{
arg_syms: vec!["input".to_string()], arg_syms: vec!["input".to_string()],
@ -126,22 +103,9 @@ mod func_tests {
Box::new(Ctr::None) Box::new(Ctr::None)
); );
{ syms.insert(String::from("echo_2"), test_external_func);
let mut table_handle = SYM_TABLE.write().unwrap();
table_handle.insert(String::from("echo_2"), test_external_func);
}
let table_handle = SYM_TABLE.read().unwrap(); match syms.call_symbol(&"echo_2".to_string(), &args, true) {
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(&args) {
Ok(ret) => assert_eq!(ret.to_string(), "(\"test\" \"test\")"), Ok(ret) => assert_eq!(ret.to_string(), "(\"test\" \"test\")"),
Err(e) => { Err(e) => {
print!("Call to function failed: {}\n", e); print!("Call to function failed: {}\n", e);
@ -154,12 +118,13 @@ mod func_tests {
#[test] #[test]
fn decl_and_call_func_with_nested_call() { fn decl_and_call_func_with_nested_call() {
let mut syms = SymTable::new();
let inner_func: Symbol = Symbol { let inner_func: Symbol = Symbol {
name: String::from("test_inner"), name: String::from("test_inner"),
has_undefined_symbols: false, conditional_branches: false,
args: Args::Strict(vec![Type::Bool]), args: Args::Strict(vec![Type::Bool]),
value: ValueType::Internal(Box::new( value: ValueType::Internal(Box::new(
|a: &Seg| -> Ctr { |a: &Seg, _: &mut SymTable| -> Ctr {
let inner = a; let inner = a;
if let Ctr::Bool(b) = *inner.car { if let Ctr::Bool(b) = *inner.car {
if b { if b {
@ -179,7 +144,7 @@ mod func_tests {
Ok(finner) => { Ok(finner) => {
let outer_func: Symbol = Symbol { let outer_func: Symbol = Symbol {
name: String::from("test_outer"), name: String::from("test_outer"),
has_undefined_symbols: false, conditional_branches: false,
args: Args::Lazy(1), args: Args::Lazy(1),
value: ValueType::FuncForm(UserFn{ value: ValueType::FuncForm(UserFn{
arg_syms: vec!["input".to_string()], arg_syms: vec!["input".to_string()],
@ -192,24 +157,10 @@ mod func_tests {
Box::new(Ctr::None) Box::new(Ctr::None)
); );
{ syms.insert(String::from("test_inner"), inner_func);
let mut table_handle = SYM_TABLE.write().unwrap(); syms.insert(String::from("test_outer"), outer_func);
table_handle.insert(String::from("test_inner"), inner_func); match syms.call_symbol(&"test_outer".to_string(), &args, true) {
table_handle.insert(String::from("test_outer"), outer_func);
}
let table_handle = SYM_TABLE.read().unwrap();
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(&args) {
Ok(ret) => match *ret { Ok(ret) => match *ret {
Ctr::String(b) => assert!(b == "test"), Ctr::String(b) => assert!(b == "test"),
_ => { _ => {