implement iseq, tests

Signed-off-by: Ava Hahn <ava@aidanis.online>
This commit is contained in:
Ava Hahn 2023-03-02 12:48:26 -08:00
parent 5ce0a8e8b2
commit cb83fa5655
Signed by untrusted user who does not match committer: affine
GPG key ID: 3A4645B8CF806069
6 changed files with 134 additions and 25 deletions

View file

@ -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

View file

@ -212,7 +212,7 @@ fn process(document: &String) -> Result<Box<Seg>, String> {
*/
fn tok_is_symbol(token: &str) -> Option<String> {
for t in token.chars() {
if !t.is_alphanumeric() && t != '-' && t != '_' {
if !t.is_alphanumeric() && t != '-' && t != '_' && t != '?' {
return None;
}
}

View file

@ -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))

View file

@ -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 {

View file

@ -55,10 +55,6 @@ pub fn bool_or_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String>
}
}
pub fn bool_xor_callback(_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
todo!()
}
pub fn bool_not_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
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<Ctr, String>
}
}
pub fn bool_iseq_callback(_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
todo!()
pub fn bool_iseq_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
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<Ctr, String> {

View file

@ -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!()
}
}
}