better if, fixes control tests
This commit is contained in:
parent
452cb7a654
commit
870b444505
2 changed files with 62 additions and 25 deletions
|
|
@ -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!()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue