finished while form

Signed-off-by: Ava Hahn <ava@aidanis.online>
This commit is contained in:
Ava Hahn 2023-03-02 15:29:50 -08:00
parent 6ef467db94
commit c235f9727f
Signed by untrusted user who does not match committer: affine
GPG key ID: 3A4645B8CF806069
5 changed files with 185 additions and 5 deletions

View file

@ -61,7 +61,7 @@ pub fn configure(filename: String, syms: &mut SymTable) -> Result<(), String> {
let mut config_document = fs::read_to_string(filename)
.unwrap_or_else(|err: io::Error| {
eprintln!("{}", err.to_string());
eprintln!("{}", err);
"".to_string()
}) + ")";

View file

@ -80,6 +80,26 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
},
);
syms.insert(
"while".to_string(),
Symbol {
name: String::from("while"),
args: Args::Infinite,
conditional_branches: true,
value: ValueType::Internal(Rc::new(control::while_callback)),
},
);
syms.insert(
"circuit".to_string(),
Symbol {
name: String::from("circuit"),
args: Args::Infinite,
conditional_branches: true,
value: ValueType::Internal(Rc::new(control::circuit_callback)),
},
);
syms.insert(
"and".to_string(),
Symbol {

View file

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