tisp

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

commit 5625aa54cbb8dca9b7bf092466a1e03e6a701b8e
parent 479672eec5349be018672c27ea9c7341e2dcca72
Author: Ed van Bruggen <edvb@uw.edu>
Date:   Tue, 10 Sep 2019 21:25:13 -0700

Evaluate procedures in own internal function

Diffstat:
tisp.c | 46++++++++++++++++++++++++++--------------------
1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/tisp.c b/tisp.c @@ -685,11 +685,35 @@ tisp_eval_list(Env env, Val v) return cdr(ret); } +static Val +eval_proc(Env env, Val v, Val f, Val args) +{ + switch (f->t) { + case PRIMITIVE: + return (*f->v.pr)(env, args); + case FUNCTION: + /* tail call into the function body with the extended env */ + if (!(args = tisp_eval_list(env, args))) + return NULL; + /* FALLTHROUGH */ + case MACRO: + tsp_arg_num(args, v->v.s, list_len(f->v.f.args)); + if (!(hash_extend(f->v.f.env->h, f->v.f.args, args))) + return NULL; + hash_merge(f->v.f.env->h, env->h); + if (f->t == MACRO) + return tisp_eval(env, list_last(tisp_eval_list(f->v.f.env, f->v.f.body))); + return list_last(tisp_eval_list(f->v.f.env, f->v.f.body)); + default: + tsp_warnf("attempt to evaluate non procedural type %s", type_str(f->t)); + } +} + /* evaluate given value */ Val tisp_eval(Env env, Val v) { - Val f, args; + Val f; switch (v->t) { case SYMBOL: if (!(f = hash_get(env->h, v->v.s))) @@ -702,25 +726,7 @@ tisp_eval(Env env, Val v) case PAIR: if (!(f = tisp_eval(env, car(v)))) return NULL; - args = cdr(v); - switch (f->t) { - case PRIMITIVE: - return (*f->v.pr)(env, args); - case FUNCTION: - /* tail call into the function body with the extended env */ - if (!(args = tisp_eval_list(env, args))) - return NULL; - case MACRO: - tsp_arg_num(args, car(v)->v.s, list_len(f->v.f.args)); - if (!(hash_extend(f->v.f.env->h, f->v.f.args, args))) - return NULL; - hash_merge(f->v.f.env->h, env->h); - if (f->t == MACRO) - return tisp_eval(env, list_last(tisp_eval_list(f->v.f.env, f->v.f.body))); - return list_last(tisp_eval_list(f->v.f.env, f->v.f.body)); - default: - tsp_warnf("attempt to evaluate non procedural type %s", type_str(f->t)); - } + return eval_proc(env, car(v), f, cdr(v)); default: return v; }