From 42169e527f74d1b7ad7cd75faf35db149076298e Mon Sep 17 00:00:00 2001 From: Felix Perktold Date: Mon, 22 Dec 2025 15:23:11 +0100 Subject: refactor apply / eval, add reverse builtin --- lisp.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'lisp.c') diff --git a/lisp.c b/lisp.c index b880eb3..be71a30 100644 --- a/lisp.c +++ b/lisp.c @@ -84,7 +84,15 @@ value *cdr(value *cons) { printf("cdr of non-pair: "); println_value(cons); return make_nil(); -} +} + +value *reverse(value *list) { + value *reversed = make_nil(); + for(value *a = list; a->type == VT_PAIR; a = cdr(a)) { + reversed = cons(car(a), reversed); + } + return reversed; +} void *println_value(value *val){ print_value(val); @@ -238,8 +246,8 @@ value *eval_pair(env *e, value *v) { } if (head->type == VT_SYMBOL && (!strcmp(head->as.sym, "lambda") || - !strcmp(head->as.sym, "\\") || - !strcmp(head->as.sym, "λ"))) { + !strcmp(head->as.sym, "\\") || + !strcmp(head->as.sym, "λ"))) { value *params = car(tail); value *body = car(cdr(tail)); @@ -268,26 +276,24 @@ value *eval_pair(env *e, value *v) { } if (head_eval->type == VT_LAMBDA) { - return apply(e, head_eval, tail); + //evaluate arguents first, then apply + value *args_eval = make_nil(); + for(value *a = tail; a->type == VT_PAIR; a = cdr(a)) { + args_eval = cons(eval(e, car(a)), args_eval); + } + return apply(head_eval, reverse(args_eval)); } return v; } -value *apply(env *e, value *lval, value *args) { +value *apply(value *lval, value *args) { env *sub_env = env_create(lval->as.lambda.env); value *params = lval->as.lambda.params; value *arg = args; while (params->type == VT_PAIR && arg->type == VT_PAIR) { - if (car(params)->type != VT_SYMBOL) { - printf("not a symbol: "); - println_value(car(params)); - return make_nil(); - } - - value *arg_eval = eval(e, car(arg)); - env_define(sub_env, car(params)->as.sym, arg_eval); + env_define(sub_env, car(params)->as.sym, car(arg)); params = cdr(params); arg = cdr(arg); } @@ -307,6 +313,10 @@ value *builtin_cdr(env *e, value *args) { return cdr(eval(e, car(args))); } +value *builtin_reverse(env *e, value *args) { + return reverse(eval(e, car(args))); +} + value *builtin_isnull(env *e, value *args) { value *v = eval(e, car(args)); if(v->type == VT_NIL) { -- cgit v1.2.3