diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-08 14:30:50 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-08 14:30:50 +0200 |
commit | 157cdbf2651503c9ef0b181796d6707faff097ad (patch) | |
tree | 22c45a476b49ff6d4b77d167d0c135df54fe591f /src/bootstrap/main.c | |
parent | aa699fc05d0945528c9ccf2b9b3d7e53e425d186 (diff) | |
download | bdl-157cdbf2651503c9ef0b181796d6707faff097ad.tar.gz bdl-157cdbf2651503c9ef0b181796d6707faff097ad.zip |
Add initial implementation of lists
Diffstat (limited to 'src/bootstrap/main.c')
-rwxr-xr-x | src/bootstrap/main.c | 76 |
1 files changed, 70 insertions, 6 deletions
diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index b346cca..a0b0f69 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c | |||
@@ -186,9 +186,16 @@ typedef struct Object { | |||
186 | 186 | ||
187 | // OBJ_TYPE_LIST | 187 | // OBJ_TYPE_LIST |
188 | struct { | 188 | struct { |
189 | struct Object **list_elems; | 189 | // NOTE: Probably want to do this as a linked list using pairs. |
190 | struct Object **list; | ||
190 | size_t list_n; | 191 | size_t list_n; |
191 | }; | 192 | }; |
193 | |||
194 | // OBJ_TYPE_SYMBOL | ||
195 | struct { | ||
196 | char *symbol; | ||
197 | size_t symbol_n; | ||
198 | }; | ||
192 | }; | 199 | }; |
193 | } Object; | 200 | } Object; |
194 | 201 | ||
@@ -219,17 +226,38 @@ make_string(const char *str, size_t n) { | |||
219 | } | 226 | } |
220 | 227 | ||
221 | Object * | 228 | Object * |
229 | make_symbol(const char *str, size_t n) { | ||
230 | Object *obj = malloc(sizeof(Object)); | ||
231 | obj->type = OBJ_TYPE_SYMBOL; | ||
232 | obj->string = malloc(sizeof(char) * n); | ||
233 | memcpy(obj->string, str, n); | ||
234 | obj->string_n = n; | ||
235 | return obj; | ||
236 | } | ||
237 | |||
238 | Object * | ||
222 | make_empty_list(void) { | 239 | make_empty_list(void) { |
223 | Object *obj = malloc(sizeof(Object)); | 240 | Object *obj = malloc(sizeof(Object)); |
224 | obj->type = OBJ_TYPE_LIST; | 241 | obj->type = OBJ_TYPE_NIL; |
225 | obj->list_elems = NULL; | 242 | obj->list = NULL; |
226 | obj->list_n = 0; | 243 | obj->list_n = 0; |
227 | return obj; | 244 | return obj; |
228 | } | 245 | } |
229 | 246 | ||
230 | void | 247 | void |
231 | push_obj_to_list(Object *list, Object obj) { | 248 | push_obj_to_list(Object *list, Object **obj) { |
232 | assert(false && "todo: Not implemented"); | 249 | assert(list != NULL); |
250 | assert(list->type == OBJ_TYPE_NIL || list->type == OBJ_TYPE_LIST); | ||
251 | |||
252 | if (obj == NULL || *obj == NULL) { | ||
253 | return; | ||
254 | } | ||
255 | |||
256 | if (list->type == OBJ_TYPE_NIL) { | ||
257 | list->type = OBJ_TYPE_LIST; | ||
258 | } | ||
259 | list->list = realloc(list->list, (list->list_n + 1) * sizeof(struct Object *)); | ||
260 | list->list[list->list_n++] = *obj; | ||
233 | } | 261 | } |
234 | 262 | ||
235 | bool | 263 | bool |
@@ -287,6 +315,29 @@ build_ast(Tokens tokens) { | |||
287 | if (sv_equal(token, FALSE_TOKEN)) { | 315 | if (sv_equal(token, FALSE_TOKEN)) { |
288 | return make_boolean(false); | 316 | return make_boolean(false); |
289 | } | 317 | } |
318 | |||
319 | // OBJ_TYPE_LIST | ||
320 | if (token.start[0] == ')') { | ||
321 | return NULL; | ||
322 | } | ||
323 | if (token.start[0] == '(') { | ||
324 | if ((i + 1) < tokens.n && tokens.start[i + 1].start[0] == ')') { | ||
325 | return make_empty_list(); | ||
326 | } | ||
327 | |||
328 | Object *list = make_empty_list(); | ||
329 | Object *next_obj = NULL; | ||
330 | while (((i + 1) < tokens.n) && (next_obj = build_ast((Tokens){&tokens.start[i + 1], tokens.n - i - 1})) != NULL) { | ||
331 | push_obj_to_list(list, &next_obj); | ||
332 | // FIXME: must consume tokens instead, otherwise recursive lists | ||
333 | // will not work. | ||
334 | i++; | ||
335 | } | ||
336 | return list; | ||
337 | } | ||
338 | |||
339 | // OBJ_TYPE_SYMBOL | ||
340 | return make_symbol(token.start, token.n); | ||
290 | } | 341 | } |
291 | 342 | ||
292 | return NULL; | 343 | return NULL; |
@@ -315,8 +366,21 @@ display(Object *root) { | |||
315 | case OBJ_TYPE_STRING: { | 366 | case OBJ_TYPE_STRING: { |
316 | printf("\"%.*s\"", (int)root->string_n, root->string); | 367 | printf("\"%.*s\"", (int)root->string_n, root->string); |
317 | } break; | 368 | } break; |
369 | case OBJ_TYPE_SYMBOL: { | ||
370 | printf(":%.*s", (int)root->symbol_n, root->symbol); | ||
371 | } break; | ||
372 | case OBJ_TYPE_LIST: { | ||
373 | printf("("); | ||
374 | for (size_t i = 0; i < root->list_n; i++) { | ||
375 | display(root->list[i]); | ||
376 | if ((i + 1) < root->list_n) { | ||
377 | printf(" "); | ||
378 | } | ||
379 | } | ||
380 | printf(")"); | ||
381 | } break; | ||
318 | default: { | 382 | default: { |
319 | printf("TYPE NOT IMPLEMENTED FOR DISPLAY\n"); | 383 | printf("TYPE NOT IMPLEMENTED FOR DISPLAY."); |
320 | } break; | 384 | } break; |
321 | } | 385 | } |
322 | } | 386 | } |