aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-08 17:53:28 +0200
committerBad Diode <bd@badd10de.dev>2021-10-08 17:53:28 +0200
commit92a1c58179183493647959838c8ad13975ece47c (patch)
treed77045a021cff90f080bdebb096e359343aea888
parent70d3ef508e10d458b89bf1eaac7238fa61376112 (diff)
downloadbdl-92a1c58179183493647959838c8ad13975ece47c.tar.gz
bdl-92a1c58179183493647959838c8ad13975ece47c.zip
Change list representation to be a linked list
-rwxr-xr-xsrc/bootstrap/main.c90
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
217typedef struct Object { 216typedef 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
249Object *empty_list;
250
253Object * 251Object *
254make_fixnum(ssize_t num) { 252make_fixnum(ssize_t num) {
255 Object *obj = malloc(sizeof(Object)); 253 Object *obj = malloc(sizeof(Object));
@@ -303,25 +301,24 @@ Object *
303make_empty_list(void) { 301make_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
311void 307Object *
312push_obj_to_list(Object *list, Object **obj) { 308make_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) { 315Object *
321 list->type = OBJ_TYPE_LIST; 316cons(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
327bool 324bool
@@ -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
421void display(Object *root);
422
423void
424display_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
419void 437void
420display(Object *root) { 438display(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
476void
477init(void) {
478 // Initialize singletons.
479 empty_list = make_empty_list();
480}
481
463int 482int
464main(void) { 483main(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);