finished while form
Signed-off-by: Ava Hahn <ava@aidanis.online>
This commit is contained in:
parent
6ef467db94
commit
c235f9727f
5 changed files with 185 additions and 5 deletions
|
|
@ -21,6 +21,7 @@ use crate::sym::{SymTable, Symbol, ValueType, Args};
|
|||
|
||||
pub fn if_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
let cond: bool;
|
||||
println!("Y: {}", *ast.car);
|
||||
match *ast.car {
|
||||
Ctr::Seg(ref cond_form) => {
|
||||
if let Ctr::Bool(cond_from_eval) = *eval(cond_form, syms)? {
|
||||
|
|
@ -30,6 +31,17 @@ pub fn if_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
|||
}
|
||||
}
|
||||
|
||||
Ctr::Symbol(ref cond_name) => {
|
||||
if let Ctr::Bool(cond_from_eval) = *syms.call_symbol(
|
||||
cond_name,
|
||||
&Seg::new(), false
|
||||
)? {
|
||||
cond = cond_from_eval;
|
||||
} else {
|
||||
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()),
|
||||
}
|
||||
|
|
@ -167,10 +179,70 @@ pub fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
|||
Ok((*result).clone())
|
||||
}
|
||||
|
||||
pub fn while_callback(_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
todo!()
|
||||
/*
|
||||
(while (cond) evalme evalme evalme evalme ... )
|
||||
*/
|
||||
pub fn while_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
let eval_cond: &Seg;
|
||||
let outer_maybe: Seg;
|
||||
let eval_bodies_head: &Seg;
|
||||
let mut unwrap = false;
|
||||
let mut result: Result<Box<Ctr>, String> = Ok(Box::new(Ctr::None));
|
||||
|
||||
if let Ctr::Seg(ref cond) = *ast.car {
|
||||
eval_cond = cond;
|
||||
} else {
|
||||
outer_maybe = Seg::from_mono(ast.car.clone());
|
||||
eval_cond = &outer_maybe;
|
||||
unwrap = true;
|
||||
}
|
||||
|
||||
if let Ctr::Seg(ref eval) = *ast.cdr {
|
||||
eval_bodies_head = eval;
|
||||
} else {
|
||||
return Err("expected N more bodies in while form".to_string())
|
||||
}
|
||||
|
||||
loop {
|
||||
let cond_res = *eval(eval_cond, syms)?;
|
||||
if unwrap {
|
||||
if let Ctr::Seg(ref cond_res_inner) = cond_res {
|
||||
if let Ctr::Bool(ref b) = *cond_res_inner.car {
|
||||
if !b {break}
|
||||
}
|
||||
} else {
|
||||
panic!()
|
||||
}
|
||||
} else if let Ctr::Bool(b) = cond_res {
|
||||
if !b {break}
|
||||
} else {
|
||||
return Err("first body of while form should evaluate to a bool".to_string())
|
||||
}
|
||||
|
||||
if !eval_bodies_head.circuit(&mut |body: &Ctr| -> bool {
|
||||
let outer_scope_seg: Seg;
|
||||
let eval_arg: &Seg;
|
||||
if let Ctr::Seg(ref eval_body) = *body {
|
||||
eval_arg = eval_body;
|
||||
} else {
|
||||
outer_scope_seg = Seg::from_mono(Box::new(body.clone()));
|
||||
eval_arg = &outer_scope_seg;
|
||||
}
|
||||
|
||||
result = eval(eval_arg, syms);
|
||||
result.is_ok()
|
||||
}) {
|
||||
return Err(result.err().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(*(result.unwrap()).clone())
|
||||
}
|
||||
|
||||
/*
|
||||
(circuit makes_a_bool makes_a_bool makes_a_bool makes_a_bool ... )
|
||||
*/
|
||||
pub fn circuit_callback(_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue