From f592d691795284c97fde06cff12a6fbdd0f856e7 Mon Sep 17 00:00:00 2001 From: Brandon Rozek Date: Sun, 10 Jun 2018 12:22:20 -0400 Subject: [PATCH] Added variable length lambda functions --- lval/environment.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/lval/environment.c b/lval/environment.c index 133b39d..5ed1a76 100644 --- a/lval/environment.c +++ b/lval/environment.c @@ -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