Fully fledged lambdas, along with efficiency tweaks across the ast
This commit is contained in:
parent
b0bd369c1d
commit
8efa1dbaad
10 changed files with 264 additions and 70 deletions
80
src/sym.rs
80
src/sym.rs
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue