diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-14 17:05:37 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-14 17:05:37 +0200 |
commit | 530ed15ec941194e661010498cf30b7842710939 (patch) | |
tree | ccd1d771350453b59049e06ac224728f321f2b15 /src/bootstrap/environment.c | |
parent | ab23395b1fc88bbc63bef88de3477cc316857ace (diff) | |
download | bdl-530ed15ec941194e661010498cf30b7842710939.tar.gz bdl-530ed15ec941194e661010498cf30b7842710939.zip |
Fix lambda and closures
Diffstat (limited to 'src/bootstrap/environment.c')
-rw-r--r-- | src/bootstrap/environment.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/src/bootstrap/environment.c b/src/bootstrap/environment.c index 99dd7fd..e111753 100644 --- a/src/bootstrap/environment.c +++ b/src/bootstrap/environment.c | |||
@@ -60,8 +60,27 @@ env_lookup(Environment *env, Object *symbol) { | |||
60 | return obj_err; | 60 | return obj_err; |
61 | } | 61 | } |
62 | 62 | ||
63 | Object * | ||
64 | env_update(Environment *env, Object *symbol, Object *value) { | ||
65 | while (env != NULL) { | ||
66 | for (size_t i = 0; i < env->size; i++) { | ||
67 | EnvEntry entry = env->buf[i]; | ||
68 | if (obj_eq(symbol, entry.symbol)) { | ||
69 | env->buf[i].value = obj_duplicate(value); | ||
70 | return obj_nil; | ||
71 | } | ||
72 | } | ||
73 | env = env->parent; | ||
74 | } | ||
75 | error_push((Error){ | ||
76 | .type = ERR_TYPE_RUNTIME, | ||
77 | .value = ERR_SYMBOL_NOT_FOUND, | ||
78 | }); | ||
79 | return obj_err; | ||
80 | } | ||
81 | |||
63 | ssize_t | 82 | ssize_t |
64 | env_symbol_index_in_current_env(Environment *env, Object *symbol) { | 83 | env_index_current(Environment *env, Object *symbol) { |
65 | for (size_t i = 0; i < env->size; i++) { | 84 | for (size_t i = 0; i < env->size; i++) { |
66 | EnvEntry entry = env->buf[i]; | 85 | EnvEntry entry = env->buf[i]; |
67 | if (obj_eq(symbol, entry.symbol)) { | 86 | if (obj_eq(symbol, entry.symbol)) { |
@@ -70,3 +89,34 @@ env_symbol_index_in_current_env(Environment *env, Object *symbol) { | |||
70 | } | 89 | } |
71 | return -1; | 90 | return -1; |
72 | } | 91 | } |
92 | |||
93 | void | ||
94 | env_add_or_update_current(Environment *env, Object *symbol, Object *value) { | ||
95 | ssize_t index = env_index_current(env, symbol); | ||
96 | if (index == -1) { | ||
97 | env_add_symbol(env, obj_duplicate(symbol), obj_duplicate(value)); | ||
98 | } else { | ||
99 | env->buf[index].value = obj_duplicate(value); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | Environment * | ||
104 | env_extend(Environment *parent, Environment *extra) { | ||
105 | Environment *env = env_create(parent); | ||
106 | for (size_t i = 0; i < extra->size; i++) { | ||
107 | EnvEntry entry = extra->buf[i]; | ||
108 | Environment *tmp = env; | ||
109 | ssize_t idx = -1; | ||
110 | while (tmp != NULL) { | ||
111 | idx = env_index_current(tmp, entry.symbol); | ||
112 | if (idx != -1) { | ||
113 | break; | ||
114 | } | ||
115 | tmp = tmp->parent; | ||
116 | } | ||
117 | if (idx == -1) { | ||
118 | env_add_symbol(env, obj_duplicate(entry.symbol), obj_duplicate(entry.value)); | ||
119 | } | ||
120 | } | ||
121 | return env; | ||
122 | } | ||