aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-30 15:36:04 +0200
committerBad Diode <bd@badd10de.dev>2021-10-30 15:36:04 +0200
commita31eff3926b4355ab9a4d7a76b0007fae0dd68b2 (patch)
tree9323792ddf4fdb38a4ab8fd693fff3f135af67c9 /src/parser.c
parent42f16c0583c348fc0a2167ff31f6cce6027307b9 (diff)
downloadbdl-a31eff3926b4355ab9a4d7a76b0007fae0dd68b2.tar.gz
bdl-a31eff3926b4355ab9a4d7a76b0007fae0dd68b2.zip
Add dead code elimination to AST tree
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c76
1 files changed, 73 insertions, 3 deletions
diff --git a/src/parser.c b/src/parser.c
index 3e6abc2..d1a5e7a 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -459,6 +459,50 @@ check_object_scope(Environment *env, Object *obj, Errors *errors) {
459 } 459 }
460} 460}
461 461
462void
463remove_unused_expr(Object *obj) {
464 if (obj == NULL) {
465 return;
466 }
467 switch (obj->type) {
468 case OBJ_TYPE_DEF:
469 case OBJ_TYPE_SET: {
470 remove_unused_expr(obj->var_expr);
471 } break;
472 case OBJ_TYPE_IF: {
473 remove_unused_expr(obj->condition);
474 remove_unused_expr(obj->expr_true);
475 remove_unused_expr(obj->expr_false);
476 } break;
477 case OBJ_TYPE_PAIR: {
478 remove_unused_expr(obj->head);
479 remove_unused_expr(obj->tail);
480 } break;
481 case OBJ_TYPE_LAMBDA: {
482 Object **new_body = NULL;
483 array_init(new_body, 0);
484 for (size_t i = 0; i < array_size(obj->body); i++) {
485 Object *expr = obj->body[i];
486 if (i != array_size(obj->body) - 1) {
487 if (IS_FIXNUM(expr) ||
488 IS_STRING(expr) ||
489 IS_SYMBOL(expr) ||
490 IS_LAMBDA(expr) ||
491 IS_BOOL(expr) ||
492 IS_NIL(expr)) {
493 continue;
494 }
495 }
496 remove_unused_expr(expr);
497 array_push(new_body, expr);
498 }
499 array_free(obj->body);
500 obj->body = new_body;
501 } break;
502 default: break;
503 }
504}
505
462Root * 506Root *
463parse(Token *tokens, Errors *errors) { 507parse(Token *tokens, Errors *errors) {
464 array_init(roots, 0); 508 array_init(roots, 0);
@@ -472,9 +516,8 @@ parse(Token *tokens, Errors *errors) {
472 // Build initial ASTs. This also ensures the core grammar is correct. 516 // Build initial ASTs. This also ensures the core grammar is correct.
473 while (has_next_token(&parser)) { 517 while (has_next_token(&parser)) {
474 Object *root = parse_tree(&parser, errors); 518 Object *root = parse_tree(&parser, errors);
475 OBJ_PRINT(root);
476 if (errors->n != 0) { 519 if (errors->n != 0) {
477 break; 520 return NULL;
478 } 521 }
479 array_push(roots, root); 522 array_push(roots, root);
480 } 523 }
@@ -498,9 +541,36 @@ parse(Token *tokens, Errors *errors) {
498 for (size_t i = 0; i < array_size(roots); i++) { 541 for (size_t i = 0; i < array_size(roots); i++) {
499 Object *root = roots[i]; 542 Object *root = roots[i];
500 check_object_scope(global_env, root, errors); 543 check_object_scope(global_env, root, errors);
544 if (errors->n != 0) {
545 return NULL;
546 }
547 }
548
549 // Remove unnecessary statements.
550 Root *final_roots = NULL;
551 array_init(final_roots, 0);
552 for (size_t i = 0; i < array_size(roots); i++) {
553 Object *root = roots[i];
554 if (i != array_size(roots) - 1) {
555 if (IS_FIXNUM(root) ||
556 IS_STRING(root) ||
557 IS_SYMBOL(root) ||
558 IS_LAMBDA(root) ||
559 IS_BOOL(root) ||
560 IS_NIL(root)) {
561 continue;
562 }
563 }
564 array_push(final_roots, root);
565
566 remove_unused_expr(root);
567 if (errors->n != 0) {
568 return NULL;
569 }
501 } 570 }
571 array_free(roots);
572 roots = final_roots;
502 573
503 // TODO: Remove unnecessary statements.
504 return roots; 574 return roots;
505} 575}
506 576