tisp

tiny lisp
git clone git://edryd.org/tisp
Log | Files | Refs | LICENSE

commit 4e9e824d3a7339dd5e973f844417867a09d7224e
parent b066e9c6dba1bbf164b41cdc975bdcc68a8a3c87
Author: Ed van Bruggen <edvb@uw.edu>
Date:   Tue, 18 Jun 2019 21:04:03 -0700

Support improper lists in last and eval_list

Diffstat:
tisp.c | 34++++++++++++++++------------------
1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/tisp.c b/tisp.c @@ -176,9 +176,9 @@ list_len(Val v) static Val list_last(Val v) { - while (!nilp(cdr(v))) + while (cdr(v)->t == PAIR) v = cdr(v); - return car(v); + return nilp(cdr(v)) ? car(v) : cdr(v); } /* check if two values are equal */ @@ -677,19 +677,21 @@ tisp_parse_file(Env env, char *fname) Val tisp_eval_list(Env env, Val v) { - int cap = 1, size = 0; - Val ret, *new = emalloc(sizeof(Val)); + Val cur = mk_pair(NULL, env->none); + Val ret = cur, ev; for (; !nilp(v); v = cdr(v)) { - if (!(new[size] = tisp_eval(env, car(v)))) - new[size] = env->none; - if (++size == cap) { - cap *= 2; - new = erealloc(new, cap*sizeof(Val)); + if (v->t != PAIR) { + if ((ev = tisp_eval(env, v))) + cdr(cur) = ev; + return cdr(ret); } + if ((ev = tisp_eval(env, car(v)))) + cdr(cur) = ev; + cdr(cur) = mk_pair(cdr(cur), env->none); + cur = cdr(cur); } - ret = mk_list(env, size, new); - free(new); - return ret; + cdr(cur) = env->nil; + return cdr(ret); } /* evaluate given value */ @@ -780,12 +782,10 @@ tisp_print(FILE *f, Val v) case PAIR: putc('(', f); list_print(f, car(v)); - v = cdr(v); - while (!nilp(v)) { + for (v = cdr(v); !nilp(v); v = cdr(v)) { if (v->t == PAIR) { putc(' ', f); list_print(f, car(v)); - v = cdr(v); } else { fprintf(f, " . "); list_print(f, v); @@ -858,9 +858,7 @@ prim_do(Env env, Val args) Val v; if (!(v = tisp_eval_list(env, args))) return NULL; - if (nilp(v)) - return env->none; - return list_last(v); + return nilp(v) ? env->none : list_last(v); } /* evaluate argument given */