diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-30 15:36:04 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-30 15:36:04 +0200 |
commit | a31eff3926b4355ab9a4d7a76b0007fae0dd68b2 (patch) | |
tree | 9323792ddf4fdb38a4ab8fd693fff3f135af67c9 /src/parser.c | |
parent | 42f16c0583c348fc0a2167ff31f6cce6027307b9 (diff) | |
download | bdl-a31eff3926b4355ab9a4d7a76b0007fae0dd68b2.tar.gz bdl-a31eff3926b4355ab9a4d7a76b0007fae0dd68b2.zip |
Add dead code elimination to AST tree
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 76 |
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 | ||
462 | void | ||
463 | remove_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 | |||
462 | Root * | 506 | Root * |
463 | parse(Token *tokens, Errors *errors) { | 507 | parse(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 | ||