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;
|
use crate::sym::SymTable;
|
||||||
|
|
||||||
pub fn if_callback (ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
pub fn if_callback (ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
||||||
if let Ctr::Seg(ref cond_form) = *ast.car {
|
let cond: bool;
|
||||||
if let Ctr::Bool(cond) = *eval(cond_form, syms)? {
|
match *ast.car {
|
||||||
if let Ctr::Seg(ref first_form) = *ast.cdr {
|
Ctr::Seg(ref cond_form) => {
|
||||||
if cond {
|
if let Ctr::Bool(cond_from_eval) = *eval(cond_form, syms)? {
|
||||||
match *first_form.car {
|
cond = cond_from_eval;
|
||||||
Ctr::Seg(ref first_arg) => Ok(*eval(first_arg, syms)?),
|
|
||||||
_ => Ok(*eval(&Seg::from_mono(first_form.car.clone()), syms)?),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let Ctr::Seg(ref second_form) = *first_form.cdr {
|
|
||||||
match *second_form.car {
|
|
||||||
Ctr::Seg(ref second_arg) => Ok(*eval(second_arg, syms)?),
|
|
||||||
_ => Ok(*eval(&Seg::from_mono(second_form.car.clone()), syms)?),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err("impossible condition: args not in standard form".to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Err("impossible condition: not 3 args to if".to_string())
|
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(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 {
|
} else {
|
||||||
Err("first argument to if must evaluate to be a boolean".to_string())
|
Err("impossible condition: args not in standard form".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!()
|
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!()
|
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!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ mod control_lib_tests {
|
||||||
if let Ctr::Integer(i) = *eval(&tree, &mut syms).unwrap() {
|
if let Ctr::Integer(i) = *eval(&tree, &mut syms).unwrap() {
|
||||||
assert_eq!(i, result);
|
assert_eq!(i, result);
|
||||||
} else {
|
} else {
|
||||||
|
eprintln!("{}", *eval(&tree, &mut syms).unwrap());
|
||||||
assert!(false);
|
assert!(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue