refmt
This commit is contained in:
parent
f805290a4b
commit
be73b0b828
17 changed files with 588 additions and 675 deletions
89
src/func.rs
89
src/func.rs
|
|
@ -15,13 +15,13 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use std::convert::TryInto;
|
||||
use std::collections::HashMap;
|
||||
use crate::segment::{Ctr, Type, circuit, list_len, list_idx, Ast};
|
||||
use crate::vars::{VTable};
|
||||
use crate::eval::eval;
|
||||
use crate::segment::{circuit, list_idx, list_len, Ast, Ctr, Type};
|
||||
use crate::vars::VTable;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryInto;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub type FTable = HashMap<String, Rc<RefCell<Function>>>;
|
||||
|
||||
|
|
@ -34,15 +34,15 @@ pub struct ExternalOperation {
|
|||
// TODO: Apply Memoization?
|
||||
pub ast: Ast,
|
||||
// list of argument string tokens
|
||||
pub arg_syms: Vec<String>
|
||||
pub arg_syms: Vec<String>,
|
||||
}
|
||||
|
||||
/* A stored function may either be a pointer to a function
|
||||
* or a syntax tree to eval with the arguments
|
||||
*/
|
||||
pub enum Operation {
|
||||
Internal(Box<dyn Fn(Ast, Rc<RefCell<VTable>>, Rc<RefCell<FTable>>)->Ctr>),
|
||||
External(ExternalOperation)
|
||||
Internal(Box<dyn Fn(Ast, Rc<RefCell<VTable>>, Rc<RefCell<FTable>>) -> Ctr>),
|
||||
External(ExternalOperation),
|
||||
}
|
||||
|
||||
/* Function Args
|
||||
|
|
@ -52,7 +52,7 @@ pub enum Operation {
|
|||
pub enum Args {
|
||||
// signed: -1 denotes infinite args
|
||||
Lazy(i128),
|
||||
Strict(Vec<Type>)
|
||||
Strict(Vec<Type>),
|
||||
}
|
||||
|
||||
// function which does not need args checked
|
||||
|
|
@ -65,7 +65,7 @@ pub struct Function {
|
|||
pub loose_syms: bool,
|
||||
|
||||
// dont evaluate args at all. leave that to the function
|
||||
pub eval_lazy: bool
|
||||
pub eval_lazy: bool,
|
||||
}
|
||||
|
||||
/* call
|
||||
|
|
@ -75,7 +75,7 @@ pub fn func_call(
|
|||
function: Rc<RefCell<Function>>,
|
||||
args: Ast,
|
||||
vars: Rc<RefCell<VTable>>,
|
||||
funcs: Rc<RefCell<FTable>>
|
||||
funcs: Rc<RefCell<FTable>>,
|
||||
) -> Result<Ctr, String> {
|
||||
let called_func = function.borrow();
|
||||
let mut n_args: Ast = args.clone();
|
||||
|
|
@ -85,16 +85,15 @@ pub fn func_call(
|
|||
if let Ctr::Seg(ast) = rc_seg {
|
||||
n_args = ast
|
||||
} else {
|
||||
return Err("Panicking: eval returned not a list for function args.".to_string())
|
||||
return Err("Panicking: eval returned not a list for function args.".to_string());
|
||||
}
|
||||
},
|
||||
Err(s) => return Err(
|
||||
format!(
|
||||
}
|
||||
Err(s) => {
|
||||
return Err(format!(
|
||||
"error evaluating args to {}: {}",
|
||||
called_func.name,
|
||||
s
|
||||
)
|
||||
)
|
||||
called_func.name, s
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -102,16 +101,12 @@ pub fn func_call(
|
|||
Args::Lazy(num) => {
|
||||
let called_arg_count = list_len(n_args.clone()) as i128;
|
||||
if *num > -1 && (*num != called_arg_count) {
|
||||
return Err(
|
||||
format!(
|
||||
"expected {} args in call to {}. Got {}.",
|
||||
num,
|
||||
called_func.name,
|
||||
called_arg_count
|
||||
)
|
||||
)
|
||||
return Err(format!(
|
||||
"expected {} args in call to {}. Got {}.",
|
||||
num, called_func.name, called_arg_count
|
||||
));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Args::Strict(arg_types) => {
|
||||
let mut idx: usize = 0;
|
||||
|
|
@ -160,17 +155,13 @@ pub fn func_call(
|
|||
}
|
||||
|
||||
match &called_func.function {
|
||||
Operation::Internal(f) => {
|
||||
return Ok(f(n_args, vars, funcs))
|
||||
},
|
||||
Operation::Internal(f) => return Ok(f(n_args, vars, funcs)),
|
||||
Operation::External(f) => {
|
||||
for n in 0..f.arg_syms.len() {
|
||||
let iter_arg = list_idx(n_args.clone(), n as u128);
|
||||
|
||||
vars.borrow_mut().insert(
|
||||
f.arg_syms[n].clone(),
|
||||
Rc::new(iter_arg)
|
||||
);
|
||||
vars.borrow_mut()
|
||||
.insert(f.arg_syms[n].clone(), Rc::new(iter_arg));
|
||||
}
|
||||
|
||||
let mut result: Ctr;
|
||||
|
|
@ -178,13 +169,11 @@ pub fn func_call(
|
|||
loop {
|
||||
if let Ctr::Seg(ast) = iterate.borrow().clone().car {
|
||||
match eval(ast, vars.clone(), funcs.clone(), called_func.loose_syms) {
|
||||
Ok(ctr) => {
|
||||
match ctr {
|
||||
Ctr::Seg(ast) => result = ast.borrow().clone().car,
|
||||
_ => result = ctr
|
||||
}
|
||||
Ok(ctr) => match ctr {
|
||||
Ctr::Seg(ast) => result = ast.borrow().clone().car,
|
||||
_ => result = ctr,
|
||||
},
|
||||
Err(e) => return Err(e)
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
} else {
|
||||
panic!("function body not in standard form!")
|
||||
|
|
@ -193,22 +182,19 @@ pub fn func_call(
|
|||
match iterate.clone().borrow().clone().cdr {
|
||||
Ctr::Seg(next) => iterate = next.clone(),
|
||||
Ctr::None => break,
|
||||
_ => panic!("function body not in standard form!")
|
||||
_ => panic!("function body not in standard form!"),
|
||||
}
|
||||
}
|
||||
for n in 0..f.arg_syms.len() {
|
||||
vars.borrow_mut().remove(&f.arg_syms[n].clone());
|
||||
}
|
||||
|
||||
return Ok(result)
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn func_declare(
|
||||
ft: Rc<RefCell<FTable>>,
|
||||
f: Rc<RefCell<Function>>
|
||||
) -> Option<String> {
|
||||
pub fn func_declare(ft: Rc<RefCell<FTable>>, f: Rc<RefCell<Function>>) -> Option<String> {
|
||||
let func = f.borrow();
|
||||
let name = func.name.clone();
|
||||
if let Operation::External(fun) = &func.function {
|
||||
|
|
@ -216,14 +202,11 @@ pub fn func_declare(
|
|||
if fun.arg_syms.len() != i.try_into().unwrap() {
|
||||
return Some(
|
||||
"external function must have lazy args equal to declared arg_syms length"
|
||||
.to_string()
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return Some(
|
||||
"external function must have lazy args"
|
||||
.to_string()
|
||||
);
|
||||
return Some("external function must have lazy args".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue