diff options
author | kartofen <mladenovnasko0@gmail.com> | 2024-09-22 15:35:40 +0300 |
---|---|---|
committer | kartofen <mladenovnasko0@gmail.com> | 2024-09-22 15:35:40 +0300 |
commit | 7edffea39a3d666098ebeca27ea398769e8b981b (patch) | |
tree | d114e34f34fdc01e1d61126a0989a1b91c449642 | |
parent | f60047d4b013eb7f75ad4f5c63eda63153a4bf8e (diff) |
make env opaque
-rw-r--r-- | src/env.c | 29 | ||||
-rw-r--r-- | src/env.h | 19 | ||||
-rw-r--r-- | src/main.c | 29 |
3 files changed, 49 insertions, 28 deletions
@@ -3,10 +3,21 @@ #include "common.h" #include "env.h" + +#include "hashtable.h" #include "value.h" +struct env { + hashtable_t table; + + struct env *parent; + size_t refs; + + env_destroy_func destroy_func; +}; + #include "mempool.h" -MEMPOOL_GENERATE(env, struct symbol_table, 64) +MEMPOOL_GENERATE(env, struct env, 64) #define ENV_TABLE_CAP (1 << 3) @@ -67,6 +78,17 @@ void env_destroy(env_t env) env_mempool_free(env); } +int env_insert(env_t env, char *key, value_t data, + char **prevkey, value_t *prevdata) +{ + return hashtable_insert(env->table, (void *)key, (void *)data, (void **)prevkey, (void **)prevdata); +} + +int env_query(env_t env, char *key, value_t *data) +{ + return hashtable_query(env->table, (void *)key, (void **)data); +} + env_t env_copy(env_t env) { if(env == ENV_EMPTY) return ENV_EMPTY; @@ -76,3 +98,8 @@ env_t env_copy(env_t env) return env; } + +env_t env_parent(env_t env) +{ + return env->parent; +} @@ -4,24 +4,19 @@ // #include "value.h" typedef struct value * _value_t; -#include "hashtable.h" - -typedef struct symbol_table *env_t; +typedef struct env * env_t; #define ENV_EMPTY NULL typedef void (*env_destroy_func)(char *key, _value_t value); -struct symbol_table { - hashtable_t table; - - struct symbol_table *parent; - size_t refs; +env_t env_create(env_t parent, env_destroy_func destroy_func); +void env_destroy(env_t env); - env_destroy_func destroy_func; -}; +int env_insert(env_t env, char *key, _value_t data, + char **prevkey, _value_t *prevdata); +int env_query(env_t env, char *key, _value_t *data); -env_t env_create(env_t parent, env_destroy_func destroy_func); env_t env_copy(env_t env); -void env_destroy(env_t env); +env_t env_parent(env_t env); #endif @@ -214,9 +214,10 @@ int main(int argc, char **argv) value_t proc_value = value_create( VALUE_PROC_BUILTIN, (void *)&builtin_proc_descriptions[i]); - hashtable_insert(builtin_env->table, - (void *)builtin_proc_name_list[i], - (void *)proc_value, NULL, NULL); + + env_insert(builtin_env, + builtin_proc_name_list[i], + proc_value, NULL, NULL); } FILE *fp = stdin; @@ -293,9 +294,9 @@ static value_t apply_lambda(struct proc *proc, value_t *args) tctx_init_toklist(&tctx, proc->body); for(size_t i = 0; i < proc->argc; i++) { - ERR_NZ(hashtable_insert(env->table, - (void*)proc->arg_keys[i]->value.atom, - (void*)value_copy(args[i]), NULL, NULL), _r, goto exit); + ERR_NZ(env_insert(env, proc->arg_keys[i]->value.atom, + value_copy(args[i]), NULL, NULL), + _r, goto exit); } TOKEN_NEXT(&tctx); @@ -458,16 +459,16 @@ value_t evaluate_id(env_t env, struct tctx *tctx) } value_t ret = VALUE_EMPTY; - ERR_NZ(hashtable_query(env->table, (void *)TOKEN(tctx)->value.id, (void **)&ret), _r, goto fail); + ERR_NZ(env_query(env, TOKEN(tctx)->value.id, &ret), _r, goto fail); return value_copy(ret); fail: - if(env == global_env->parent) { + if(env == env_parent(global_env)) { err("Symbol %s is unbound", TOKEN(tctx)->value.id); return VALUE_EMPTY; } - return evaluate_id(env->parent, tctx); + return evaluate_id(env_parent(env), tctx); } value_t evaluate_lambda(env_t env, struct tctx *tctx) @@ -558,10 +559,9 @@ value_t evaluate_define(env_t env, struct tctx *tctx) char *prevkey = NULL; ERR_NZ( - hashtable_insert(global_env->table, (void *)key, (void *)val, - (void**)&prevkey, (void **)&prevval), + env_insert(global_env, key, val, &prevkey, &prevval), r, { - err("Couldn't insert symbol into the hashtable due to %s", strerror(r)); + err("Couldn't insert symbol into the environement due to %s", strerror(r)); value_destroy(val); // the copy goto fail; }); @@ -643,10 +643,9 @@ value_t evaluate_defmacro(env_t env, struct tctx *tctx) char *prevkey = NULL; ERR_NZ( - hashtable_insert(global_env->table, (void *)key, (void *)lambda, - (void**)&prevkey, (void **)&prevval), + env_insert(global_env, key, lambda, &prevkey, &prevval), r, { - err("Couldn't insert symbol into the hashtable due to %s", strerror(r)); + err("Couldn't insert symbol into the environement due to %s", strerror(r)); goto fail; }); |