diff --git a/lval/environment.c b/lval/environment.c index 86a5b22..975387a 100644 --- a/lval/environment.c +++ b/lval/environment.c @@ -93,4 +93,32 @@ void lenv_add_builtins(lenv* e) { lenv_add_builtin(e, "%", builtin_mod); lenv_add_builtin(e, "min", builtin_min); lenv_add_builtin(e, "max", builtin_max); + + lenv_add_builtin(e, "def", builtin_def); +} + +lval* builtin_def(lenv* e, lval* a) { + LASSERT(a, a->cell[0]->type == LVAL_QEXPR, + "Function 'def' passed incorrect type") + + // First argument is the symbol list + lval* syms = a->cell[0]; + + // Ensure all elements of the first list are symbols + for (int i = 0; i < syms->count; i++) { + LASSERT(a, syms->cell[i]->type == LVAL_SYM, + "Function 'def' cannot define non-symbol") + } + + // Check correct number of symbols and values + LASSERT(a, syms->count == a->count - 1, + "Function 'def' cannot define incorrect number of values to symbols") + + // Assign copies of values to symbols + for (int i = 0; i < syms->count; i++) { + lenv_put(e, syms->cell[i], a->cell[i + 1]); + } + + lval_del(a); + return lval_sexpr(); } \ No newline at end of file diff --git a/lval/environment.h b/lval/environment.h index 6845af3..6444731 100644 --- a/lval/environment.h +++ b/lval/environment.h @@ -21,5 +21,7 @@ lval* lval_fun(lbuiltin func); void lenv_add_builtin(lenv* e, char* name, lbuiltin func); void lenv_add_builtins(lenv* e); +lval* builtin_def(lenv* e, lval* a); + #endif diff --git a/prompt.c b/prompt.c index f56c269..9aa616e 100644 --- a/prompt.c +++ b/prompt.c @@ -96,6 +96,8 @@ int main (int argc, char** argv) { free(input); } + lenv_del(e); + mpc_cleanup(8, Number, Long, Double, Symbol, Sexpr, Qexpr, Expr, Lispy); return 0; }