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.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/bootstrap/environment.c b/src/bootstrap/environment.c
new file mode 100644
index 0000000..1bbe844
--- /dev/null
+++ b/src/bootstrap/environment.c
@@ -0,0 +1,106 @@
1//
2// Environment.
3//
4
5typedef struct EnvEntry {
6 Object *symbol;
7 Object *value;
8} EnvEntry;
9
10typedef struct Environment {
11 struct Environment *parent;
12 EnvEntry *buf;
13 size_t size;
14 size_t cap;
15} Environment;
16
17static Environment *global_env;
18
19#define ENV_BUF_CAP 8
20
21Environment *
22env_create(Environment *parent) {
23 Environment *env = malloc(sizeof(Environment));
24 env->parent = parent;
25 env->buf = NULL;
26 env->size = 0;
27 env->cap = ENV_BUF_CAP;
28 return env;
29}
30
31void
32env_add_symbol(Environment *env, Object *symbol, Object *value) {
33 if (symbol->type != OBJ_TYPE_SYMBOL) {
34 error_push((Error){
35 .type = ERR_TYPE_RUNTIME,
36 .value = ERR_NOT_A_SYMBOL,
37 .line = 0,
38 .col = 0,
39 });
40 return;
41 }
42 if (env->buf == NULL) {
43 env->size = 0;
44 env->cap = ENV_BUF_CAP;
45 env->buf = malloc(env->cap * sizeof(EnvEntry));
46 } else if (env->size == env->cap) {
47 env->cap *= 2;
48 env->buf = realloc(env->buf, env->cap * sizeof(EnvEntry));
49 }
50 env->buf[env->size++] = (EnvEntry){symbol, value};
51}
52
53bool
54obj_eq(Object *a, Object* b) {
55 if (a->type != b->type) {
56 return false;
57 }
58 switch (a->type) {
59 case OBJ_TYPE_FIXNUM: {
60 return a->fixnum == b->fixnum;
61 } break;
62 case OBJ_TYPE_STRING: {
63 if (a->string_n != b->string_n) {
64 return false;
65 }
66 for (size_t i = 0; i < a->string_n; i++) {
67 if (a->string[i] != b->string[i]) {
68 return false;
69 }
70 }
71 } break;
72 case OBJ_TYPE_SYMBOL: {
73 if (a->symbol_n != b->symbol_n) {
74 return false;
75 }
76 for (size_t i = 0; i < a->symbol_n; i++) {
77 if (a->symbol[i] != b->symbol[i]) {
78 return false;
79 }
80 }
81 } break;
82 case OBJ_TYPE_PAIR: {
83 // TODO: needs evaluation of parameters...
84 } break;
85 default: {
86 return a == b;
87 } break;
88 }
89 return true;
90}
91
92Object *
93env_lookup(Environment *env, Object *symbol) {
94 while (env != NULL) {
95 for (size_t i = 0; i < env->size; i++) {
96 EnvEntry entry = env->buf[i];
97 if (obj_eq(symbol, entry.symbol)) {
98 return entry.value;
99 }
100 }
101 env = env->parent;
102 }
103 return obj_err;
104}
105
106// TODO: Free env function.