From cb83fa5655e2f712b904426260f7ca17a64e1444 Mon Sep 17 00:00:00 2001 From: Ava Hahn Date: Thu, 2 Mar 2023 12:48:26 -0800 Subject: [PATCH] implement iseq, tests Signed-off-by: Ava Hahn --- Readme.org | 7 --- src/lex.rs | 2 +- src/segment.rs | 19 ++++++- src/stl.rs | 10 ---- src/stl/boolean.rs | 9 ++-- tests/test_lib_bools.rs | 112 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 134 insertions(+), 25 deletions(-) diff --git a/Readme.org b/Readme.org index 8d33218..467fdce 100644 --- a/Readme.org +++ b/Readme.org @@ -154,13 +154,6 @@ Will need a concatenate function for tables **** TODO queue (append to front) **** TODO snippet for dequeue **** TODO snippet for pop -*** TODO boolean operations -**** DONE and (circuit) -**** DONE or -**** TODO xor -**** DONE no -**** TODO eq? -**** DONE toggle *** TODO string operations **** TODO typecast (string) **** TODO contains diff --git a/src/lex.rs b/src/lex.rs index ca93293..b695151 100644 --- a/src/lex.rs +++ b/src/lex.rs @@ -212,7 +212,7 @@ fn process(document: &String) -> Result, String> { */ fn tok_is_symbol(token: &str) -> Option { for t in token.chars() { - if !t.is_alphanumeric() && t != '-' && t != '_' { + if !t.is_alphanumeric() && t != '-' && t != '_' && t != '?' { return None; } } diff --git a/src/segment.rs b/src/segment.rs index d4c73ab..82c284b 100644 --- a/src/segment.rs +++ b/src/segment.rs @@ -49,7 +49,7 @@ pub enum Type { * I was going to call it Cell and then I learned about * how important RefCells were in Rust */ -#[derive(Debug, Default)] +#[derive(Debug, Default, PartialEq)] pub struct Seg { /* "Contents of Address Register" * Historical way of referring to the first value in a cell. @@ -251,6 +251,23 @@ impl fmt::Display for Ctr { } } +impl PartialEq for Ctr { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Ctr::Symbol(r), Ctr::Symbol(l)) => *r == *l, + (Ctr::String(r), Ctr::String(l)) => *r == *l, + (Ctr::Bool(r), Ctr::Bool(l)) => *r == *l, + (Ctr::Seg(r), Ctr::Seg(l)) => *r == *l, + (Ctr::None, Ctr::None) => true, + (Ctr::Integer(r), Ctr::Integer(l)) => *r == *l, + (Ctr::Float(r), Ctr::Float(l)) => *r == *l, + (Ctr::Integer(r), Ctr::Float(l)) => *r < f64::MAX as i128 && *r as f64 == *l, + (Ctr::Float(r), Ctr::Integer(l)) => *l < f64::MAX as i128 && *r == *l as f64, + _ => false, + } + } +} + impl fmt::Display for Seg { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", seg_to_string(self, true)) diff --git a/src/stl.rs b/src/stl.rs index 1f534dd..040a4c8 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -100,16 +100,6 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> { } ); - syms.insert( - "xor".to_string(), - Symbol { - name: String::from("xor"), - args: Args::Infinite, - conditional_branches: false, - value: ValueType::Internal(Rc::new(boolean::bool_xor_callback)), - } - ); - syms.insert( "not".to_string(), Symbol { diff --git a/src/stl/boolean.rs b/src/stl/boolean.rs index f0f39da..8bbbd0d 100644 --- a/src/stl/boolean.rs +++ b/src/stl/boolean.rs @@ -55,10 +55,6 @@ pub fn bool_or_callback(ast: &Seg, _syms: &mut SymTable) -> Result } } -pub fn bool_xor_callback(_ast: &Seg, _syms: &mut SymTable) -> Result { - todo!() -} - pub fn bool_not_callback(ast: &Seg, _syms: &mut SymTable) -> Result { if let Ctr::Bool(b) = *ast.car { Ok(Ctr::Bool(!b)) @@ -67,8 +63,9 @@ pub fn bool_not_callback(ast: &Seg, _syms: &mut SymTable) -> Result } } -pub fn bool_iseq_callback(_ast: &Seg, _syms: &mut SymTable) -> Result { - todo!() +pub fn bool_iseq_callback(ast: &Seg, _syms: &mut SymTable) -> Result { + let head_ctr_ref = &*ast.car; + Ok(Ctr::Bool(ast.circuit(&mut |arg: &Ctr| -> bool {arg == head_ctr_ref}))) } pub fn bool_toggle_callback(ast: &Seg, syms: &mut SymTable) -> Result { diff --git a/tests/test_lib_bools.rs b/tests/test_lib_bools.rs index ce64efd..a3f2151 100644 --- a/tests/test_lib_bools.rs +++ b/tests/test_lib_bools.rs @@ -238,4 +238,116 @@ mod bool_lib_tests { panic!() } } + + #[test] + fn test_iseq_basic_t() { + let document = "(eq? true true)"; + let test = lex(&document.to_string()).unwrap(); + + let mut syms = SymTable::new(); + static_stdlib(&mut syms).unwrap(); + dynamic_stdlib(&mut syms).unwrap(); + + if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { + assert!(b) + } else { + panic!() + } + } + + #[test] + fn test_iseq_basic_f() { + let document = "(eq? true false)"; + let test = lex(&document.to_string()).unwrap(); + + let mut syms = SymTable::new(); + static_stdlib(&mut syms).unwrap(); + dynamic_stdlib(&mut syms).unwrap(); + + if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { + assert!(!b) + } else { + panic!() + } + } + + #[test] + fn test_iseq_basic_f_mixed_data() { + let document = "(eq? true 1)"; + let test = lex(&document.to_string()).unwrap(); + + let mut syms = SymTable::new(); + static_stdlib(&mut syms).unwrap(); + dynamic_stdlib(&mut syms).unwrap(); + + if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { + assert!(!b) + } else { + panic!() + } + } + + #[test] + fn test_iseq_long_f() { + let document = "(eq? true true true true true false)"; + let test = lex(&document.to_string()).unwrap(); + + let mut syms = SymTable::new(); + static_stdlib(&mut syms).unwrap(); + dynamic_stdlib(&mut syms).unwrap(); + + if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { + assert!(!b) + } else { + panic!() + } + } + + #[test] + fn test_iseq_long_t_str() { + let document = "(eq? '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1')"; + let test = lex(&document.to_string()).unwrap(); + + let mut syms = SymTable::new(); + static_stdlib(&mut syms).unwrap(); + dynamic_stdlib(&mut syms).unwrap(); + + if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { + assert!(b) + } else { + panic!() + } + } + + #[test] + fn test_iseq_t_mixed_numerals() { + let document = "(eq? 1 1.0)"; + let test = lex(&document.to_string()).unwrap(); + + let mut syms = SymTable::new(); + static_stdlib(&mut syms).unwrap(); + dynamic_stdlib(&mut syms).unwrap(); + + if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { + assert!(b) + } else { + panic!() + } + } + + #[test] + fn test_iseq_f_wrong_type() { + let document = "(eq? 1 '1')"; + let test = lex(&document.to_string()).unwrap(); + + let mut syms = SymTable::new(); + static_stdlib(&mut syms).unwrap(); + dynamic_stdlib(&mut syms).unwrap(); + + if let Ctr::Bool(b) = *eval(&test, &mut syms).unwrap() { + assert!(!b) + } else { + panic!() + } + } }