* fixed and wrote test for lambda and function as arg case

* added license to userlib tests
* added map impl to userlib
* userlib tests now run and pass
* all args are evaluated individually
This commit is contained in:
Ava Apples Affine 2023-03-20 16:22:51 -07:00
parent 8a91560921
commit dcb2969b0a
Signed by: affine
GPG key ID: 3A4645B8CF806069
7 changed files with 148 additions and 40 deletions

View file

@ -110,7 +110,16 @@ impl SymTable {
let cond_args: &Seg;
let outer_scope_seg_holder: Seg;
if let ValueType::VarForm(ref val) = symbol.value {
return Ok(val.clone());
match **val {
Ctr::Lambda(ref l) if call_func => {
return call_lambda(
l,
&Box::new(Ctr::Seg(args.clone())),
self
)
},
_ => return Ok(val.clone()),
}
} else if call_func {
cond_args = args
} else {
@ -122,8 +131,12 @@ impl SymTable {
}
pub fn is_function_type(&self, name: &String) -> Option<bool> {
if let ValueType::VarForm(_) = self.get(name)?.value {
Some(false)
if let ValueType::VarForm(ref val) = self.get(name)?.value {
if let Ctr::Lambda(_) = **val {
Some(true)
} else {
Some(false)
}
} else {
Some(true)
}
@ -270,17 +283,36 @@ impl Symbol {
*/
pub fn call(&self, args: &Seg, syms: &mut SymTable) -> Result<Box<Ctr>, String> {
let evaluated_args: &Seg;
let outer_scope_seg_storage: Seg;
let outer_scope_eval: Box<Ctr>;
let mut outer_scope_seg_storage = Seg::new();
let mut errcon: String = String::new();
if !self.conditional_branches {
outer_scope_eval = eval(args, syms)?;
match *outer_scope_eval {
Ctr::Seg(ref segment) => evaluated_args = segment,
_ => {
outer_scope_seg_storage = Seg::from_mono(outer_scope_eval);
evaluated_args = &outer_scope_seg_storage;
if !args.circuit(&mut |arg: &Ctr| -> bool {
if let Ctr::Seg(ref s) = arg {
let eval_res = eval(s, syms);
if eval_res.is_err() {
errcon = eval_res.err().unwrap();
return false
}
outer_scope_seg_storage.append(eval_res.unwrap().clone());
} else if let Ctr::Symbol(ref s) = arg {
let eval_res = syms.call_symbol(
s,
&outer_scope_seg_storage,
false
);
if eval_res.is_err() {
errcon = eval_res.err().unwrap();
return false
}
outer_scope_seg_storage.append(eval_res.unwrap().clone());
} else {
outer_scope_seg_storage.append(Box::new(arg.clone()));
}
true
}) {
return Err(format!("error evaluating args: {}", errcon))
}
evaluated_args = &outer_scope_seg_storage;
} else {
evaluated_args = args;
}
@ -294,7 +326,7 @@ impl Symbol {
// If this ever becomes ASYNC this will need to
// become a more traditional stack design, and the
// global table will need to be released
let mut holding_table = SymTable::new();
let mut holding_table = SymTable::new();
// Prep var table for function execution
for n in 0..f.arg_syms.len() {
@ -370,9 +402,6 @@ impl Symbol {
arg_syms: arg_syms.clone(),
});
args = Args::Lazy(arg_syms.len() as u128);
} else if let Ctr::Lambda(ref l) = *ast.car {
args = Args::Lazy(l.arg_syms.len() as u128);
value = ValueType::FuncForm(l.clone());
} else {
args = Args::None;
value = ValueType::VarForm(ast.car.clone());