finished let forms

Signed-off-by: Ava Hahn <ava@aidanis.online>
This commit is contained in:
Ava Hahn 2023-03-01 15:17:50 -08:00
parent 131008c3a2
commit c1d83a6285
Signed by untrusted user who does not match committer: affine
GPG key ID: 3A4645B8CF806069
5 changed files with 198 additions and 27 deletions

View file

@ -69,6 +69,16 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
},
);
syms.insert(
"let".to_string(),
Symbol {
name: String::from("let"),
args: Args::Infinite,
conditional_branches: true,
value: ValueType::Internal(Rc::new(control::let_callback)),
},
);
Ok(())
}

View file

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

View file

@ -19,6 +19,8 @@ use crate::eval::eval;
use crate::segment::{Ctr, Seg, Type};
use std::collections::HashMap;
use std::rc::Rc;
#[derive(Clone)]
pub struct SymTable(HashMap<String, Symbol>);
#[derive(Debug, Clone)]