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.c52
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
63Object *
64env_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
63ssize_t 82ssize_t
64env_symbol_index_in_current_env(Environment *env, Object *symbol) { 83env_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
93void
94env_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
103Environment *
104env_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}