aboutsummaryrefslogtreecommitdiffstats
path: root/src/bootstrap/environment.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootstrap/environment.c')
-rw-r--r--src/bootstrap/environment.c59
1 files changed, 14 insertions, 45 deletions
diff --git a/src/bootstrap/environment.c b/src/bootstrap/environment.c
index cb9e2f0..dd4a648 100644
--- a/src/bootstrap/environment.c
+++ b/src/bootstrap/environment.c
@@ -7,8 +7,7 @@ env_create(Environment *parent) {
7 Environment *env = alloc_env(); 7 Environment *env = alloc_env();
8 env->parent = parent; 8 env->parent = parent;
9 env->marked = false; 9 env->marked = false;
10 env->entries = NULL; 10 env->table = ht_init();
11 array_init(env->entries, ENV_BUF_CAP);
12 return env; 11 return env;
13} 12}
14 13
@@ -23,18 +22,15 @@ env_add_symbol(Environment *env, Object *symbol, Object *value) {
23 }); 22 });
24 return; 23 return;
25 } 24 }
26 EnvEntry entry = (EnvEntry){symbol, value}; 25 ht_insert(env->table, symbol, value);
27 array_push(env->entries, entry);
28} 26}
29 27
30Object * 28Object *
31env_lookup(Environment *env, Object *symbol) { 29env_lookup(Environment *env, Object *symbol) {
32 while (env != NULL) { 30 while (env != NULL) {
33 for (size_t i = 0; i < array_size(env->entries); i++) { 31 Object *obj = ht_lookup(env->table, symbol);
34 EnvEntry entry = env->entries[i]; 32 if (obj != NULL) {
35 if (obj_eq(symbol, entry.symbol)) { 33 return obj;
36 return entry.value;
37 }
38 } 34 }
39 env = env->parent; 35 env = env->parent;
40 } 36 }
@@ -44,12 +40,10 @@ env_lookup(Environment *env, Object *symbol) {
44Object * 40Object *
45env_update(Environment *env, Object *symbol, Object *value) { 41env_update(Environment *env, Object *symbol, Object *value) {
46 while (env != NULL) { 42 while (env != NULL) {
47 for (size_t i = 0; i < array_size(env->entries); i++) { 43 Object *obj = ht_lookup(env->table, symbol);
48 EnvEntry entry = env->entries[i]; 44 if (obj != NULL) {
49 if (obj_eq(symbol, entry.symbol)) { 45 ht_insert(env->table, symbol, value);
50 env->entries[i].value = value; 46 return obj_nil;
51 return obj_nil;
52 }
53 } 47 }
54 env = env->parent; 48 env = env->parent;
55 } 49 }
@@ -60,43 +54,18 @@ env_update(Environment *env, Object *symbol, Object *value) {
60 return obj_err; 54 return obj_err;
61} 55}
62 56
63ssize_t
64env_index_current(Environment *env, Object *symbol) {
65 for (size_t i = 0; i < array_size(env->entries); i++) {
66 EnvEntry entry = env->entries[i];
67 if (obj_eq(symbol, entry.symbol)) {
68 return i;
69 }
70 }
71 return -1;
72}
73
74void 57void
75env_add_or_update_current(Environment *env, Object *symbol, Object *value) { 58env_add_or_update_current(Environment *env, Object *symbol, Object *value) {
76 ssize_t index = env_index_current(env, symbol); 59 ht_insert(env->table, symbol, value);
77 if (index == -1) {
78 env_add_symbol(env, symbol, value);
79 } else {
80 env->entries[index].value = value;
81 }
82} 60}
83 61
84Environment * 62Environment *
85env_extend(Environment *parent, Environment *extra) { 63env_extend(Environment *parent, Environment *extra) {
86 Environment *env = parent; 64 Environment *env = parent;
87 for (size_t i = 0; i < array_size(extra->entries); i++) { 65 HashTablePair *pairs = extra->table->pairs;
88 EnvEntry entry = extra->entries[i]; 66 for (size_t i = 0; i < array_cap(pairs); i++) {
89 Environment *tmp = env; 67 if (pairs[i].key != NULL) {
90 bool found = false; 68 ht_insert(env->table, pairs[i].key, pairs[i].value);
91 while (tmp != NULL) {
92 if (env_index_current(tmp, entry.symbol) != -1) {
93 found = true;
94 break;
95 }
96 tmp = tmp->parent;
97 }
98 if (!found) {
99 env_add_symbol(env, entry.symbol, entry.value);
100 } 69 }
101 } 70 }
102 return env; 71 return env;