diff options
Diffstat (limited to 'src/bootstrap/environment.c')
-rw-r--r-- | src/bootstrap/environment.c | 59 |
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 | ||
30 | Object * | 28 | Object * |
31 | env_lookup(Environment *env, Object *symbol) { | 29 | env_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) { | |||
44 | Object * | 40 | Object * |
45 | env_update(Environment *env, Object *symbol, Object *value) { | 41 | env_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 | ||
63 | ssize_t | ||
64 | env_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 | |||
74 | void | 57 | void |
75 | env_add_or_update_current(Environment *env, Object *symbol, Object *value) { | 58 | env_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 | ||
84 | Environment * | 62 | Environment * |
85 | env_extend(Environment *parent, Environment *extra) { | 63 | env_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; |