aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-08 14:30:50 +0200
committerBad Diode <bd@badd10de.dev>2021-10-08 14:30:50 +0200
commit157cdbf2651503c9ef0b181796d6707faff097ad (patch)
tree22c45a476b49ff6d4b77d167d0c135df54fe591f
parentaa699fc05d0945528c9ccf2b9b3d7e53e425d186 (diff)
downloadbdl-157cdbf2651503c9ef0b181796d6707faff097ad.tar.gz
bdl-157cdbf2651503c9ef0b181796d6707faff097ad.zip
Add initial implementation of lists
-rwxr-xr-xsrc/bootstrap/main.c76
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
221Object * 228Object *
229make_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
238Object *
222make_empty_list(void) { 239make_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
230void 247void
231push_obj_to_list(Object *list, Object obj) { 248push_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
235bool 263bool
@@ -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}