Fully fledged lambdas, along with efficiency tweaks across the ast

This commit is contained in:
Ava Apples Affine 2023-03-13 15:02:19 -07:00
parent b0bd369c1d
commit 8efa1dbaad
Signed by: affine
GPG key ID: 3A4645B8CF806069
10 changed files with 264 additions and 70 deletions

View file

@ -229,11 +229,15 @@ impl fmt::Display for Args {
impl fmt::Display for UserFn {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "(lambda: (");
for i in self.arg_syms {
write!(f, "{} ", i);
write!(f, "(lambda (")?;
let mut arg_iter = (&self.arg_syms).into_iter();
if let Some(elem) = arg_iter.next() {
write!(f, "{}", elem)?;
for i in arg_iter {
write!(f, " {}", i)?;
}
}
write!(f, ") {})", self.ast);
write!(f, ") {})", self.ast.car)?;
Ok(())
}
@ -265,12 +269,7 @@ impl Symbol {
let outer_scope_seg_storage: Seg;
let outer_scope_eval: Box<Ctr>;
if !self.conditional_branches {
let outer_scope_eval_result = eval(args, syms);
// dont listen to clippy. using ? will move the value.
if let Err(s) = outer_scope_eval_result {
return Err(s);
}
outer_scope_eval = outer_scope_eval_result.unwrap();
outer_scope_eval = eval(args, syms)?;
match *outer_scope_eval {
Ctr::Seg(ref segment) => evaluated_args = segment,
_ => {
@ -282,6 +281,7 @@ impl Symbol {
evaluated_args = args;
}
println!("args: {}", evaluated_args);
self.args.validate_inputs(evaluated_args)?;
match &self.value {
ValueType::VarForm(ref f) => Ok(Box::new(*f.clone())),
@ -351,4 +351,64 @@ impl Symbol {
}
}
}
pub fn from_ast(
id: &String,
doc: &String,
ast: &Seg,
arg_list: Option<Vec<String>>,
) -> Symbol {
let args: Args;
let value: ValueType;
if let Some(ref arg_syms) = arg_list {
println!("def a func form");
value = ValueType::FuncForm(UserFn{
ast: Box::new(ast.clone()),
arg_syms: arg_syms.clone(),
});
args = Args::Lazy(arg_syms.len() as u128);
} else if let Ctr::Lambda(ref l) = *ast.car {
println!("def a func form (lambda)");
args = Args::Lazy(l.arg_syms.len() as u128);
value = ValueType::FuncForm(l.clone());
} else {
println!("def a var form");
args = Args::None;
value = ValueType::VarForm(ast.car.clone());
}
Symbol {
name: id.clone(),
docs: doc.clone(),
conditional_branches: false,
args, value,
}
}
}
pub fn call_lambda(
lam: &UserFn,
args_ctr: &Box<Ctr>,
syms: &mut SymTable,
) -> Result<Box<Ctr>, String> {
let temp_sym = Symbol {
name: String::from("anonymous"),
conditional_branches: false,
docs: String::from("user defined lambda"),
args: Args::Lazy(lam.arg_syms.len() as u128),
value: ValueType::FuncForm(lam.clone()),
};
let args: &Seg;
let outer_scope_maybe_args: Seg;
if let Ctr::Seg(ref args_head) = **args_ctr {
args = args_head;
} else {
outer_scope_maybe_args = Seg::from_mono(
Box::new(*args_ctr.clone()));
args = &outer_scope_maybe_args;
}
temp_sym.call(args, syms)
}