finished let forms
Signed-off-by: Ava Hahn <ava@aidanis.online>
This commit is contained in:
parent
131008c3a2
commit
c1d83a6285
5 changed files with 198 additions and 27 deletions
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
use crate::eval::eval;
|
||||
use crate::segment::{Ctr, Seg};
|
||||
use crate::sym::SymTable;
|
||||
use crate::sym::{SymTable, Symbol, ValueType, Args};
|
||||
|
||||
pub fn if_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
let cond: bool;
|
||||
|
|
@ -46,7 +46,6 @@ pub fn if_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
|||
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 {
|
||||
|
|
@ -62,7 +61,6 @@ pub fn if_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
|||
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 {
|
||||
|
|
@ -78,18 +76,104 @@ pub fn if_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn let_callback(_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
todo!()
|
||||
pub fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
let mut localsyms = syms.clone();
|
||||
let locals_form: &Seg;
|
||||
let eval_forms: &Seg;
|
||||
if let Ctr::Seg(ref locals_form_list) = *ast.car {
|
||||
locals_form = locals_form_list;
|
||||
} else {
|
||||
return Err("first element of let form must contain local variables".to_string())
|
||||
}
|
||||
|
||||
if let Ctr::Seg(ref eval_forms_head) = *ast.cdr {
|
||||
eval_forms = eval_forms_head;
|
||||
} else {
|
||||
return Err("let form should contain one or more elements to evaluate".to_string())
|
||||
}
|
||||
|
||||
// process locals forms
|
||||
if !locals_form.circuit(&mut |var_decl: &Ctr| -> bool {
|
||||
if let Ctr::Seg(ref var_form) = *var_decl {
|
||||
if let Ctr::Symbol(ref name) = *var_form.car {
|
||||
if let Ctr::Seg(ref var_val_form) = *var_form.cdr {
|
||||
let var_val_res: Result<Box<Ctr>, String>;
|
||||
if let Ctr::Seg(ref val_form) = *var_val_form.car {
|
||||
var_val_res = eval(val_form, &mut localsyms);
|
||||
} else {
|
||||
let var_tree = Seg::from_mono(Box::new(*var_val_form.car.clone()));
|
||||
let intermediate = eval(&var_tree, &mut localsyms);
|
||||
if intermediate.is_err() {
|
||||
var_val_res = intermediate;
|
||||
} else if let Ctr::Seg(ref intermediate_result) = *intermediate.unwrap() {
|
||||
var_val_res = Ok(intermediate_result.car.clone())
|
||||
} else {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
if let Err(e) = var_val_res {
|
||||
eprintln!("failed to evaluate definition of {}: {}", name, e);
|
||||
return false
|
||||
}
|
||||
|
||||
let temp = var_val_res.clone().unwrap();
|
||||
println!("dbg: {}", temp);
|
||||
|
||||
localsyms.insert(name.clone(), Symbol {
|
||||
name: name.clone(),
|
||||
args: Args::None,
|
||||
conditional_branches: false,
|
||||
value: ValueType::VarForm(Box::new(*var_val_res.unwrap().clone())),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
eprintln!("improper declaration of {}: not a list", var_decl);
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
eprintln!("improper declaration form: {}", var_decl);
|
||||
return false
|
||||
}
|
||||
true
|
||||
}) {
|
||||
return Err("local variable declaration failure".to_string())
|
||||
}
|
||||
|
||||
let mut result: Box<Ctr> = Box::new(Ctr::None);
|
||||
if !eval_forms.circuit(&mut |eval_form: &Ctr| -> bool {
|
||||
let res: Result<Box<Ctr>, String>;
|
||||
if let Ctr::Seg(ref eval_tree) = eval_form {
|
||||
res = eval(&eval_tree, &mut localsyms);
|
||||
} else {
|
||||
let eval_tree = Seg::from_mono(Box::new(eval_form.clone()));
|
||||
let intermediate = eval(&eval_tree, &mut localsyms);
|
||||
if intermediate.is_err() {
|
||||
res = intermediate;
|
||||
} else if let Ctr::Seg(ref intermediate_result) = *intermediate.unwrap() {
|
||||
res = Ok(intermediate_result.car.clone())
|
||||
} else {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = res {
|
||||
eprintln!("error evaluating let form: {}", e);
|
||||
return false
|
||||
}
|
||||
|
||||
result = res.unwrap().clone();
|
||||
true
|
||||
}) {
|
||||
return Err("evaluation failure".to_string())
|
||||
}
|
||||
|
||||
Ok((*result).clone())
|
||||
}
|
||||
|
||||
pub fn while_callback(_ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
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!()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue