From 6fcdb655a6581963a873224ad01f92b4e88f0de3 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sun, 17 Oct 2021 16:08:58 +0200 Subject: Cleanup if call in eval function --- src/bootstrap/primitives.c | 84 ++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 51 deletions(-) (limited to 'src/bootstrap/primitives.c') diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c index 0403e3a..ab147d4 100644 --- a/src/bootstrap/primitives.c +++ b/src/bootstrap/primitives.c @@ -1,6 +1,5 @@ #define DEBUG_OBJ(MSG,OBJ) printf((MSG)); display(OBJ); printf("\n"); - -Object * proc_if(Environment *env, Object *obj); +static Object *proc_if; Object * eval(Environment *env, Object *root) { @@ -41,32 +40,34 @@ eval_start: }); return obj_err; } - if (val->type == OBJ_TYPE_PROCEDURE) { - // TODO: This is very messy, needs refactoring. - if (val->proc == proc_if) { - Object *obj = root->cdr; - if (obj == obj_nil || obj->cdr == obj_nil) { - error_push((Error){ - .type = ERR_TYPE_RUNTIME, - .value = ERR_NOT_ENOUGH_ARGS, - }); - return obj_err; - } - Object *car = obj->car; - Object *cdr = obj->cdr; - Object *condition = eval(env, car); - if (condition == obj_err) { - return obj_err; - } - if (condition == obj_true) { - root = cdr->car; - } else if (cdr->cdr != obj_nil) { - root = cdr->cdr->car; - } else { - return obj_nil; - } - goto eval_start; + + // Primitive `if` procedure with TCO. + if (val == proc_if) { + Object *obj = root->cdr; + if (obj == obj_nil || obj->cdr == obj_nil) { + error_push((Error){ + .type = ERR_TYPE_RUNTIME, + .value = ERR_NOT_ENOUGH_ARGS, + }); + return obj_err; } + Object *car = obj->car; + Object *cdr = obj->cdr; + Object *condition = eval(env, car); + if (condition == obj_err) { + return obj_err; + } + if (condition == obj_true) { + root = cdr->car; + } else if (cdr->cdr != obj_nil) { + root = cdr->cdr->car; + } else { + return obj_nil; + } + goto eval_start; + } + + if (val->type == OBJ_TYPE_PROCEDURE) { ret = val->proc(env, root->cdr); goto eval_success; } @@ -138,6 +139,11 @@ eval_lambda: root = root->car; goto eval_start; } + error_push((Error){ + .type = ERR_TYPE_RUNTIME, + .value = ERR_OBJ_NOT_CALLABLE, + }); + return obj_err; } break; } @@ -482,30 +488,6 @@ proc_or(Environment *env, Object *obj) { return obj_false; } -Object * -proc_if(Environment *env, Object *obj) { - if (obj == obj_nil || obj->cdr == obj_nil) { - error_push((Error){ - .type = ERR_TYPE_RUNTIME, - .value = ERR_NOT_ENOUGH_ARGS, - }); - return obj_err; - } - Object *car = obj->car; - Object *cdr = obj->cdr; - Object *condition = eval(env, car); - if (condition == obj_err) { - return obj_err; - } - if (condition == obj_true) { - return eval(env, cdr->car); - } - if (cdr->cdr != obj_nil) { - return eval(env, cdr->cdr->car); - } - return obj_nil; -} - Object * proc_cond(Environment *env, Object *obj) { if (obj == obj_nil) { -- cgit v1.2.1