#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; }