in progress commit
- fixed errors in func and vars blocking testing - use box references in call and eval Still need to fix the tests themselves....
This commit is contained in:
parent
d2f60314f9
commit
76b12a8214
5 changed files with 44 additions and 63 deletions
55
src/func.rs
55
src/func.rs
|
|
@ -25,7 +25,7 @@ use crate::eval::eval;
|
|||
pub type FTable = HashMap<String, Box<Function>>;
|
||||
|
||||
// Standardized function signature for stdlib functions
|
||||
pub type InternalOperation = fn(Box<Cell>, Box<VTable>, Box<FTable>) -> Box<Cell>;
|
||||
pub type InternalOperation = fn(&Box<Cell>, &mut Box<VTable>, &mut Box<FTable>) -> Box<Cell>;
|
||||
pub struct ExternalOperation {
|
||||
// Un-evaluated abstract syntax tree
|
||||
// TODO: Intermediate evaluation to simplify branches with no argument in them
|
||||
|
|
@ -46,7 +46,7 @@ pub enum Operation {
|
|||
|
||||
/* Function Args
|
||||
* If Lazy, is an integer denoting number of args
|
||||
* If Strict, is a list of Ctrs (with no wrapped values) denoting arg type.
|
||||
* If Strict, is a list of type tags denoting argument type.
|
||||
*/
|
||||
pub enum Args {
|
||||
// signed: -1 denotes infinite args
|
||||
|
|
@ -73,14 +73,15 @@ impl Function {
|
|||
*/
|
||||
pub fn call(
|
||||
&self,
|
||||
args: Box<Cell>,
|
||||
vars: Box<VTable>,
|
||||
funcs: Box<FTable>
|
||||
args: &Box<Cell>,
|
||||
vars: &mut Box<VTable>,
|
||||
funcs: &mut Box<FTable>
|
||||
) -> Result<Box<Cell>, String> {
|
||||
let mut n_args = args;
|
||||
let n_args: &Box<Cell>;
|
||||
let outer_owner: Box<Cell>;
|
||||
if !self.eval_lazy {
|
||||
match eval(args, vars, funcs, self.loose_syms) {
|
||||
Ok(box_cell) => n_args = box_cell,
|
||||
Ok(box_cell) => outer_owner = box_cell,
|
||||
Err(s) => return Err(
|
||||
format!(
|
||||
"error evaluating args to {}: {}",
|
||||
|
|
@ -89,21 +90,24 @@ impl Function {
|
|||
)
|
||||
)
|
||||
}
|
||||
n_args = &outer_owner;
|
||||
} else {
|
||||
n_args = args;
|
||||
}
|
||||
|
||||
match self.args {
|
||||
match &self.args {
|
||||
Args::Lazy(num) => {
|
||||
if num < 0 {
|
||||
if *num < 0 {
|
||||
}
|
||||
|
||||
if !(num == (n_args.len() - 1)) {
|
||||
if !(*num == (n_args.len() - 1)) {
|
||||
return Err(format!("expected {} args in call to {}", num, self.name))
|
||||
}
|
||||
},
|
||||
|
||||
Args::Strict(arg_types) => {
|
||||
let idx: usize = 0;
|
||||
let mut passes = args.circuit(|c: Ctr| {
|
||||
let mut idx: usize = 0;
|
||||
let passes = n_args.circuit(&mut |c: &Ctr| {
|
||||
if idx >= arg_types.len() {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -147,28 +151,28 @@ impl Function {
|
|||
}
|
||||
}
|
||||
|
||||
match self.function {
|
||||
Operation::Internal(f) => Ok((f)(n_args, vars, funcs)),
|
||||
match &self.function {
|
||||
Operation::Internal(f) => Ok((f)(&n_args, vars, funcs)),
|
||||
Operation::External(f) => {
|
||||
// copy var table and add args
|
||||
let temp = vars.clone();
|
||||
let mut temp = vars.clone();
|
||||
for n in 0..f.arg_syms.len() {
|
||||
temp.insert(
|
||||
f.arg_syms[n],
|
||||
f.arg_syms[n].clone(),
|
||||
Box::new(n_args.index(n))
|
||||
);
|
||||
}
|
||||
eval(f.ast, temp, funcs, self.loose_syms)
|
||||
eval(&f.ast, &temp, funcs, self.loose_syms)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declare(
|
||||
ft: Box<FTable>,
|
||||
ft: &mut Box<FTable>,
|
||||
f: Box<Function>
|
||||
) -> Option<String> {
|
||||
if let Operation::External(fun) = f.function {
|
||||
if let Operation::External(fun) = &f.function {
|
||||
if let Args::Lazy(i) = f.args {
|
||||
if fun.arg_syms.len() != i.try_into().unwrap() {
|
||||
return Some(
|
||||
|
|
@ -184,17 +188,6 @@ pub fn declare(
|
|||
}
|
||||
}
|
||||
|
||||
ft.insert(f.name, f);
|
||||
ft.insert(f.name.clone(), f);
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get(
|
||||
ft: Box<FTable>,
|
||||
identifier: String
|
||||
) -> Option<Box<Function>> {
|
||||
if let Some(f) = ft.get(&identifier) {
|
||||
Some(*f)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue