From eeff5e273f22aa28e81ab080e9ffdce85ac394b8 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 22 Oct 2021 09:59:31 +0200 Subject: Prepare skeleton for bytecode interpreter --- src/treewalk/environment.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/treewalk/environment.c (limited to 'src/treewalk/environment.c') diff --git a/src/treewalk/environment.c b/src/treewalk/environment.c new file mode 100644 index 0000000..dd4a648 --- /dev/null +++ b/src/treewalk/environment.c @@ -0,0 +1,72 @@ +#include "environment.h" +#include "gc.h" +#include "errors.h" + +Environment * +env_create(Environment *parent) { + Environment *env = alloc_env(); + env->parent = parent; + env->marked = false; + env->table = ht_init(); + return env; +} + +void +env_add_symbol(Environment *env, Object *symbol, Object *value) { + if (symbol->type != OBJ_TYPE_SYMBOL) { + error_push((Error){ + .type = ERR_TYPE_RUNTIME, + .value = ERR_NOT_A_SYMBOL, + .line = 0, + .col = 0, + }); + return; + } + ht_insert(env->table, symbol, value); +} + +Object * +env_lookup(Environment *env, Object *symbol) { + while (env != NULL) { + Object *obj = ht_lookup(env->table, symbol); + if (obj != NULL) { + return obj; + } + env = env->parent; + } + return obj_err; +} + +Object * +env_update(Environment *env, Object *symbol, Object *value) { + while (env != NULL) { + Object *obj = ht_lookup(env->table, symbol); + if (obj != NULL) { + ht_insert(env->table, symbol, value); + return obj_nil; + } + env = env->parent; + } + error_push((Error){ + .type = ERR_TYPE_RUNTIME, + .value = ERR_SYMBOL_NOT_FOUND, + }); + return obj_err; +} + +void +env_add_or_update_current(Environment *env, Object *symbol, Object *value) { + ht_insert(env->table, symbol, value); +} + +Environment * +env_extend(Environment *parent, Environment *extra) { + Environment *env = parent; + HashTablePair *pairs = extra->table->pairs; + for (size_t i = 0; i < array_cap(pairs); i++) { + if (pairs[i].key != NULL) { + ht_insert(env->table, pairs[i].key, pairs[i].value); + } + } + return env; +} -- cgit v1.2.1