diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/bootstrap/main.c | 90 |
1 files changed, 55 insertions, 35 deletions
diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index 241697a..a8e39f5 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c | |||
@@ -211,7 +211,6 @@ typedef enum ObjectType { | |||
211 | OBJ_TYPE_SYMBOL, | 211 | OBJ_TYPE_SYMBOL, |
212 | OBJ_TYPE_STRING, | 212 | OBJ_TYPE_STRING, |
213 | OBJ_TYPE_PAIR, | 213 | OBJ_TYPE_PAIR, |
214 | OBJ_TYPE_LIST, | ||
215 | } ObjectType; | 214 | } ObjectType; |
216 | 215 | ||
217 | typedef struct Object { | 216 | typedef struct Object { |
@@ -235,13 +234,6 @@ typedef struct Object { | |||
235 | struct Object *cdr; | 234 | struct Object *cdr; |
236 | }; | 235 | }; |
237 | 236 | ||
238 | // OBJ_TYPE_LIST | ||
239 | struct { | ||
240 | // NOTE: Probably want to do this as a linked list using pairs. | ||
241 | struct Object **list; | ||
242 | size_t list_n; | ||
243 | }; | ||
244 | |||
245 | // OBJ_TYPE_SYMBOL | 237 | // OBJ_TYPE_SYMBOL |
246 | struct { | 238 | struct { |
247 | char *symbol; | 239 | char *symbol; |
@@ -250,6 +242,12 @@ typedef struct Object { | |||
250 | }; | 242 | }; |
251 | } Object; | 243 | } Object; |
252 | 244 | ||
245 | // | ||
246 | // Singletons. | ||
247 | // | ||
248 | |||
249 | Object *empty_list; | ||
250 | |||
253 | Object * | 251 | Object * |
254 | make_fixnum(ssize_t num) { | 252 | make_fixnum(ssize_t num) { |
255 | Object *obj = malloc(sizeof(Object)); | 253 | Object *obj = malloc(sizeof(Object)); |
@@ -303,25 +301,24 @@ Object * | |||
303 | make_empty_list(void) { | 301 | make_empty_list(void) { |
304 | Object *obj = malloc(sizeof(Object)); | 302 | Object *obj = malloc(sizeof(Object)); |
305 | obj->type = OBJ_TYPE_NIL; | 303 | obj->type = OBJ_TYPE_NIL; |
306 | obj->list = NULL; | ||
307 | obj->list_n = 0; | ||
308 | return obj; | 304 | return obj; |
309 | } | 305 | } |
310 | 306 | ||
311 | void | 307 | Object * |
312 | push_obj_to_list(Object *list, Object **obj) { | 308 | make_procedure(Object *(*proc)(struct Object *args)) { |
313 | assert(list != NULL); | 309 | Object *obj = malloc(sizeof(Object)); |
314 | assert(list->type == OBJ_TYPE_NIL || list->type == OBJ_TYPE_LIST); | 310 | obj->type = OBJ_TYPE_PROCEDURE; |
315 | 311 | obj->proc = proc; | |
316 | if (obj == NULL || *obj == NULL) { | 312 | return obj; |
317 | return; | 313 | } |
318 | } | ||
319 | 314 | ||
320 | if (list->type == OBJ_TYPE_NIL) { | 315 | Object * |
321 | list->type = OBJ_TYPE_LIST; | 316 | cons(Object *car, Object *cdr) { |
322 | } | 317 | Object *obj = malloc(sizeof(Object)); |
323 | list->list = realloc(list->list, (list->list_n + 1) * sizeof(struct Object *)); | 318 | obj->type = OBJ_TYPE_PAIR; |
324 | list->list[list->list_n++] = *obj; | 319 | obj->car = car; |
320 | obj->cdr = cdr; | ||
321 | return obj; | ||
325 | } | 322 | } |
326 | 323 | ||
327 | bool | 324 | bool |
@@ -389,15 +386,20 @@ build_ast(Tokens *tokens) { | |||
389 | } | 386 | } |
390 | if (token->start[0] == '(') { | 387 | if (token->start[0] == '(') { |
391 | if (tokens->n > 0 && tokens->start[0].start[0] == ')') { | 388 | if (tokens->n > 0 && tokens->start[0].start[0] == ')') { |
392 | return make_empty_list(); | 389 | return empty_list; |
393 | } | 390 | } |
394 | 391 | ||
395 | Object *list = make_empty_list(); | 392 | Object *next_obj = build_ast(tokens); |
396 | Object *next_obj = NULL; | 393 | if (next_obj == NULL) { |
394 | return NULL; | ||
395 | } | ||
396 | Object *root = cons(next_obj, empty_list); | ||
397 | Object *list = root; | ||
397 | while (tokens->n > 0 && (next_obj = build_ast(tokens)) != NULL) { | 398 | while (tokens->n > 0 && (next_obj = build_ast(tokens)) != NULL) { |
398 | push_obj_to_list(list, &next_obj); | 399 | list->cdr = cons(next_obj, empty_list); |
400 | list = list->cdr; | ||
399 | } | 401 | } |
400 | return list; | 402 | return root; |
401 | } | 403 | } |
402 | 404 | ||
403 | // OBJ_TYPE_STRING | 405 | // OBJ_TYPE_STRING |
@@ -416,6 +418,22 @@ build_ast(Tokens *tokens) { | |||
416 | return NULL; | 418 | return NULL; |
417 | } | 419 | } |
418 | 420 | ||
421 | void display(Object *root); | ||
422 | |||
423 | void | ||
424 | display_pair(Object *root) { | ||
425 | display(root->car); | ||
426 | if (root->cdr->type == OBJ_TYPE_PAIR) { | ||
427 | printf(" "); | ||
428 | display_pair(root->cdr); | ||
429 | } else if (root->cdr->type == OBJ_TYPE_NIL) { | ||
430 | return; | ||
431 | } else { | ||
432 | printf(" . "); | ||
433 | display(root->cdr); | ||
434 | } | ||
435 | } | ||
436 | |||
419 | void | 437 | void |
420 | display(Object *root) { | 438 | display(Object *root) { |
421 | if (root == NULL) { | 439 | if (root == NULL) { |
@@ -442,14 +460,9 @@ display(Object *root) { | |||
442 | case OBJ_TYPE_SYMBOL: { | 460 | case OBJ_TYPE_SYMBOL: { |
443 | printf(":%.*s", (int)root->symbol_n, root->symbol); | 461 | printf(":%.*s", (int)root->symbol_n, root->symbol); |
444 | } break; | 462 | } break; |
445 | case OBJ_TYPE_LIST: { | 463 | case OBJ_TYPE_PAIR: { |
446 | printf("("); | 464 | printf("("); |
447 | for (size_t i = 0; i < root->list_n; i++) { | 465 | display_pair(root); |
448 | display(root->list[i]); | ||
449 | if ((i + 1) < root->list_n) { | ||
450 | printf(" "); | ||
451 | } | ||
452 | } | ||
453 | printf(")"); | 466 | printf(")"); |
454 | } break; | 467 | } break; |
455 | default: { | 468 | default: { |
@@ -460,8 +473,15 @@ display(Object *root) { | |||
460 | 473 | ||
461 | #define REPL_PROMPT "bdl> " | 474 | #define REPL_PROMPT "bdl> " |
462 | 475 | ||
476 | void | ||
477 | init(void) { | ||
478 | // Initialize singletons. | ||
479 | empty_list = make_empty_list(); | ||
480 | } | ||
481 | |||
463 | int | 482 | int |
464 | main(void) { | 483 | main(void) { |
484 | init(); | ||
465 | printf("BDL REPL (Press Ctrl-C to exit)\n"); | 485 | printf("BDL REPL (Press Ctrl-C to exit)\n"); |
466 | while (true) { | 486 | while (true) { |
467 | printf(REPL_PROMPT); | 487 | printf(REPL_PROMPT); |