From 14814ecbf53760654aab34e0613abf347a54113f Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Thu, 14 Oct 2021 18:06:54 +0200 Subject: Add fun sugar for function variable declaration --- src/bootstrap/environment.c | 8 ++++---- src/bootstrap/main.c | 1 + src/bootstrap/objects.c | 4 ++-- src/bootstrap/primitives.c | 43 +++++++++++++++++++++++++++++++++++++++---- 4 files changed, 46 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/bootstrap/environment.c b/src/bootstrap/environment.c index e111753..78f31fb 100644 --- a/src/bootstrap/environment.c +++ b/src/bootstrap/environment.c @@ -106,15 +106,15 @@ env_extend(Environment *parent, Environment *extra) { for (size_t i = 0; i < extra->size; i++) { EnvEntry entry = extra->buf[i]; Environment *tmp = env; - ssize_t idx = -1; + bool found = false; while (tmp != NULL) { - idx = env_index_current(tmp, entry.symbol); - if (idx != -1) { + if (env_index_current(tmp, entry.symbol) != -1) { + found = true; break; } tmp = tmp->parent; } - if (idx == -1) { + if (!found) { env_add_symbol(env, obj_duplicate(entry.symbol), obj_duplicate(entry.value)); } } diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index 7591834..5191fd0 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c @@ -76,6 +76,7 @@ init(void) { MAKE_ENV_PROC(global_env, "def", proc_define); MAKE_ENV_PROC(global_env, "set!", proc_set); MAKE_ENV_PROC(global_env, "lambda", proc_lambda); + MAKE_ENV_PROC(global_env, "fun", proc_fun); // Runtime procedures. MAKE_ENV_PROC(global_env, "supress-errors", proc_supress_errors); diff --git a/src/bootstrap/objects.c b/src/bootstrap/objects.c index b3aa3de..b03a616 100644 --- a/src/bootstrap/objects.c +++ b/src/bootstrap/objects.c @@ -41,7 +41,7 @@ typedef struct Object { // OBJ_TYPE_LAMBDA struct { - struct Object *args; + struct Object *params; struct Object *body; struct Environment *env; }; @@ -186,7 +186,7 @@ free_objects(Object *root) { free(root); } break; case OBJ_TYPE_LAMBDA: { - free_objects(root->args); + free_objects(root->params); free_objects(root->body); // TODO: free_env(root->env); free(root); diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c index 4ef56d5..4c3e4c6 100644 --- a/src/bootstrap/primitives.c +++ b/src/bootstrap/primitives.c @@ -54,7 +54,7 @@ eval_lambda: if (lambda->type == OBJ_TYPE_LAMBDA) { Object *fun = lambda; Object *args = root->cdr; - Object *params = fun->args; + Object *params = fun->params; env = env_extend(fun->env, env); while (params != obj_nil) { if (args == obj_nil) { @@ -742,8 +742,8 @@ proc_lambda(Environment *env, Object *obj) { }); return obj_err; } - Object *args = obj->car; - if (args != obj_nil && args->type != OBJ_TYPE_PAIR) { + Object *params = obj->car; + if (params != obj_nil && params->type != OBJ_TYPE_PAIR) { error_push((Error){ .type = ERR_TYPE_RUNTIME, .value = ERR_WRONG_ARG_TYPE, @@ -752,12 +752,47 @@ proc_lambda(Environment *env, Object *obj) { } Object *body = obj->cdr; Object *fun = alloc_object(OBJ_TYPE_LAMBDA); - fun->args = obj_duplicate(args); + fun->params = obj_duplicate(params); fun->body = obj_duplicate(body); fun->env = env; return fun; } +Object * +proc_fun(Environment *env, Object *obj) { + if (obj == obj_nil || obj->cdr == obj_nil || obj->cdr->cdr == obj_nil) { + error_push((Error){ + .type = ERR_TYPE_RUNTIME, + .value = ERR_NOT_ENOUGH_ARGS, + }); + return obj_err; + } + + Object *name = obj->car; + if (name->type != OBJ_TYPE_SYMBOL) { + error_push((Error){ + .type = ERR_TYPE_RUNTIME, + .value = ERR_WRONG_ARG_TYPE, + }); + return obj_err; + } + + Object *params = obj->cdr->car; + if (params != obj_nil && params->type != OBJ_TYPE_PAIR) { + error_push((Error){ + .type = ERR_TYPE_RUNTIME, + .value = ERR_WRONG_ARG_TYPE, + }); + return obj_err; + } + Object *body = obj->cdr->cdr; + Object *fun = alloc_object(OBJ_TYPE_LAMBDA); + fun->params = obj_duplicate(params); + fun->body = obj_duplicate(body); + fun->env = env; + env_add_or_update_current(env, name, fun); + return obj_nil; +} // // Evaluation. -- cgit v1.2.1