better if, fixes control tests

This commit is contained in:
Ava Hahn 2023-02-28 11:12:27 -08:00
parent 452cb7a654
commit 870b444505
Signed by untrusted user who does not match committer: affine
GPG key ID: 3A4645B8CF806069
2 changed files with 62 additions and 25 deletions

View file

@ -20,43 +20,79 @@ use crate::eval::eval;
use crate::sym::SymTable;
pub fn if_callback (ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
if let Ctr::Seg(ref cond_form) = *ast.car {
if let Ctr::Bool(cond) = *eval(cond_form, syms)? {
if let Ctr::Seg(ref first_form) = *ast.cdr {
if cond {
match *first_form.car {
Ctr::Seg(ref first_arg) => Ok(*eval(first_arg, syms)?),
_ => Ok(*eval(&Seg::from_mono(first_form.car.clone()), syms)?),
}
let cond: bool;
match *ast.car {
Ctr::Seg(ref cond_form) => {
if let Ctr::Bool(cond_from_eval) = *eval(cond_form, syms)? {
cond = cond_from_eval;
} else {
if let Ctr::Seg(ref second_form) = *first_form.cdr {
match *second_form.car {
return Err("first argument to if must evaluate to be a boolean".to_string())
}
}
Ctr::Bool(cond_from_car) => cond = cond_from_car,
_ => {
return Err("first argument to if must evaluate to be a boolean".to_string())
}
}
let then_form: &Seg;
if let Ctr::Seg(ref s) = *ast.cdr {
then_form = s;
} else {
return Err("impossible condition: not enough args to if".to_string())
}
if cond {
// then
match *then_form.car {
Ctr::Seg(ref first_arg) => Ok(*eval(first_arg, syms)?),
_ => {
//Ok(*eval(&Seg::from_mono(then_form.car.clone()), syms)?)},
let eval_tree = &Seg::from_mono(then_form.car.clone());
let eval_res = *eval(eval_tree, syms)?;
if let Ctr::Seg(ref s) = eval_res {
Ok(*s.car.clone())
} else {
Err("impossible condition: list evals to non list".to_string())
}
},
}
} else {
// else
if let Ctr::Seg(ref else_form) = *then_form.cdr {
match *else_form.car {
Ctr::Seg(ref second_arg) => Ok(*eval(second_arg, syms)?),
_ => Ok(*eval(&Seg::from_mono(second_form.car.clone()), syms)?),
_ => {
//Ok(*eval(&Seg::from_mono(then_form.car.clone()), syms)?)},
let eval_tree = &Seg::from_mono(else_form.car.clone());
let eval_res = *eval(eval_tree, syms)?;
if let Ctr::Seg(ref s) = eval_res {
Ok(*s.car.clone())
} else {
Err("impossible condition: list evals to non list".to_string())
}
},
}
} else {
Err("impossible condition: args not in standard form".to_string())
}
}
} else {
Err("impossible condition: not 3 args to if".to_string())
}
} else {
Err("first argument to if must evaluate to be a boolean".to_string())
}
} else {
Err("impossible condition: not 3 args to if".to_string())
}
}
fn let_callback (_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
pub fn let_callback (_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
todo!()
}
fn while_callback (_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
pub fn while_callback (_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
todo!()
}
fn map_callback (_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
pub fn map_callback (_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
todo!()
}
pub fn circuit_callback (_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
todo!()
}

View file

@ -35,6 +35,7 @@ mod control_lib_tests {
if let Ctr::Integer(i) = *eval(&tree, &mut syms).unwrap() {
assert_eq!(i, result);
} else {
eprintln!("{}", *eval(&tree, &mut syms).unwrap());
assert!(false);
}
} else {