* 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:
parent
8a91560921
commit
dcb2969b0a
7 changed files with 148 additions and 40 deletions
59
src/sym.rs
59
src/sym.rs
|
|
@ -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());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue