WIP lambda

* typesystem extended
* docstrings and callback
* tests defined, not implemented
This commit is contained in:
Ava Apples Affine 2023-03-12 20:29:39 -07:00
parent 7befdc869b
commit b0bd369c1d
Signed by: affine
GPG key ID: 3A4645B8CF806069
4 changed files with 88 additions and 24 deletions

View file

@ -244,3 +244,44 @@ pub fn env_callback(_ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
}
Ok(Ctr::None)
}
pub const LAMBDA_DOCSTRING: &str = "Takes two arguments of any type.
No args are evaluated when lambda is called.
Lambda makes sure the first argument is a list of symbols (or 'arguments') to the lambda function.
The next arg is stored in a tree to evaluate on demand.
Example: (lambda (x y) (add x y))
This can then be evaluated like so:
((lambda (x y) (add x y)) 1 2)
which is functionally equivalent to:
(add 1 2)";
pub fn lambda_callback(
ast: &Seg,
_syms: &mut SymTable
) -> Result<Ctr, String> {
let mut args = vec![];
if let Ctr::Seg(ref arg_head) = *ast.car {
if !arg_head.circuit(&mut |arg: &Ctr| -> bool {
if let Ctr::Symbol(ref s) = *arg {
args.push(s.clone());
true
} else {
false
}
}) {
Err("all elements of first argumnets must be symbols".to_string())
} else {
if let Ctr::Seg(ref eval_head) = *ast.cdr {
Ok(Ctr::Lambda(UserFn{
ast: Box::new(eval_head.clone()),
arg_syms: args,
}))
} else {
Err("not enough args".to_string())
}
}
} else {
Err("first argument should be a list of symbols".to_string())
}
}