From 530ed15ec941194e661010498cf30b7842710939 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Thu, 14 Oct 2021 17:05:37 +0200 Subject: Fix lambda and closures --- src/bootstrap/environment.c | 52 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'src/bootstrap/environment.c') diff --git a/src/bootstrap/environment.c b/src/bootstrap/environment.c index 99dd7fd..e111753 100644 --- a/src/bootstrap/environment.c +++ b/src/bootstrap/environment.c @@ -60,8 +60,27 @@ env_lookup(Environment *env, Object *symbol) { return obj_err; } +Object * +env_update(Environment *env, Object *symbol, Object *value) { + while (env != NULL) { + for (size_t i = 0; i < env->size; i++) { + EnvEntry entry = env->buf[i]; + if (obj_eq(symbol, entry.symbol)) { + env->buf[i].value = obj_duplicate(value); + return obj_nil; + } + } + env = env->parent; + } + error_push((Error){ + .type = ERR_TYPE_RUNTIME, + .value = ERR_SYMBOL_NOT_FOUND, + }); + return obj_err; +} + ssize_t -env_symbol_index_in_current_env(Environment *env, Object *symbol) { +env_index_current(Environment *env, Object *symbol) { for (size_t i = 0; i < env->size; i++) { EnvEntry entry = env->buf[i]; if (obj_eq(symbol, entry.symbol)) { @@ -70,3 +89,34 @@ env_symbol_index_in_current_env(Environment *env, Object *symbol) { } return -1; } + +void +env_add_or_update_current(Environment *env, Object *symbol, Object *value) { + ssize_t index = env_index_current(env, symbol); + if (index == -1) { + env_add_symbol(env, obj_duplicate(symbol), obj_duplicate(value)); + } else { + env->buf[index].value = obj_duplicate(value); + } +} + +Environment * +env_extend(Environment *parent, Environment *extra) { + Environment *env = env_create(parent); + for (size_t i = 0; i < extra->size; i++) { + EnvEntry entry = extra->buf[i]; + Environment *tmp = env; + ssize_t idx = -1; + while (tmp != NULL) { + idx = env_index_current(tmp, entry.symbol); + if (idx != -1) { + break; + } + tmp = tmp->parent; + } + if (idx == -1) { + env_add_symbol(env, obj_duplicate(entry.symbol), obj_duplicate(entry.value)); + } + } + return env; +} -- cgit v1.2.1