Added variable length lambda functions
This commit is contained in:
parent
e6924523cf
commit
f592d69179
1 changed files with 36 additions and 0 deletions
|
@ -235,6 +235,21 @@ lval* lval_call(lenv* e, lval* f, lval* a) {
|
|||
// Pop the first symbol from the formals
|
||||
lval* sym = lval_pop(f->formals, 0);
|
||||
|
||||
if (strcmp(sym->sym, "&") == 0) {
|
||||
// Ensure '&' is followed by another symbol
|
||||
if (f->formals->count != 1) {
|
||||
lval_del(a);
|
||||
return lval_err("Function format invalid."
|
||||
"Symbol '&' not followed by single symbol.");
|
||||
}
|
||||
|
||||
// Next formal should be bounded to remaining arguments
|
||||
lval* nsym = lval_pop(f->formals, 0);
|
||||
lenv_put(f->env, nsym, builtin_list(e, a));
|
||||
lval_del(sym); lval_del(nsym);
|
||||
break;
|
||||
}
|
||||
|
||||
// Pop the next argument from the list
|
||||
lval* val = lval_pop(a, 0);
|
||||
|
||||
|
@ -248,6 +263,27 @@ lval* lval_call(lenv* e, lval* f, lval* a) {
|
|||
// The argument list is now bounded so we can clean up the given
|
||||
lval_del(a);
|
||||
|
||||
// If '&' remains in formal list bind to empty list
|
||||
if (f->formals->count > 0 &&
|
||||
strcmp(f->formals->cell[0]->sym, "&") == 0) {
|
||||
// Check to ensure that & is no passed invalidly
|
||||
if (f->formals->count != 2) {
|
||||
return lval_err("Function format invalid."
|
||||
"Symbol '&' not followed by single symbol.");
|
||||
}
|
||||
|
||||
// Pop and delete '&' symbol
|
||||
lval_del(lval_pop(f->formals, 0));
|
||||
|
||||
// Pop next symbol and create empty list
|
||||
lval* sym = lval_pop(f->formals, 0);
|
||||
lval* val = lval_qexpr();
|
||||
|
||||
// Bind to environment and delete
|
||||
lenv_put(f->env, sym, val);
|
||||
lval_del(sym); lval_del(val);
|
||||
}
|
||||
|
||||
// If all formals have been bounded evaluate
|
||||
if (f->formals->count == 0) {
|
||||
// Set environment parent to evaluation environment
|
||||
|
|
Reference in a new issue