diff options
author | Bad Diode <bd@badd10de.dev> | 2022-04-07 12:41:34 -0300 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2022-04-07 12:41:34 -0300 |
commit | 9f934cbc0f0fd60a6938ac1c4c84edc270de94ca (patch) | |
tree | 9304f9bc802eac175b594de4bf81730b7d815513 /src/parser.c | |
parent | a718a62a45b081bfd2cff8da56da2d2856ca244b (diff) | |
download | bdl-9f934cbc0f0fd60a6938ac1c4c84edc270de94ca.tar.gz bdl-9f934cbc0f0fd60a6938ac1c4c84edc270de94ca.zip |
Add initial implementation of typeclass resolution
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 89 |
1 files changed, 84 insertions, 5 deletions
diff --git a/src/parser.c b/src/parser.c index 841a516..cf7aebb 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -505,7 +505,9 @@ symbol_check(Parser *parser, Node *node) { | |||
505 | case NODE_BUILTIN: { | 505 | case NODE_BUILTIN: { |
506 | for (size_t i = 0; i < array_size(node->builtin.args); ++i) { | 506 | for (size_t i = 0; i < array_size(node->builtin.args); ++i) { |
507 | Node *arg = node->builtin.args[i]; | 507 | Node *arg = node->builtin.args[i]; |
508 | symbol_check(parser, arg); | 508 | if (!symbol_check(parser, arg)) { |
509 | return false; | ||
510 | } | ||
509 | } | 511 | } |
510 | } break; | 512 | } break; |
511 | case NODE_SYMBOL: { | 513 | case NODE_SYMBOL: { |
@@ -541,10 +543,14 @@ symbol_check(Parser *parser, Node *node) { | |||
541 | body->scope = parser->parse_tree->current_scope; | 543 | body->scope = parser->parse_tree->current_scope; |
542 | for (size_t i = 0; i < array_size(body->block.expr); ++i) { | 544 | for (size_t i = 0; i < array_size(body->block.expr); ++i) { |
543 | Node *expr = body->block.expr[i]; | 545 | Node *expr = body->block.expr[i]; |
544 | symbol_check(parser, expr); | 546 | if (!symbol_check(parser, expr)) { |
547 | return false; | ||
548 | } | ||
545 | } | 549 | } |
546 | } else { | 550 | } else { |
547 | symbol_check(parser, body); | 551 | if (!symbol_check(parser, body)) { |
552 | return false; | ||
553 | } | ||
548 | } | 554 | } |
549 | parser->parse_tree->current_scope = prev_scope; | 555 | parser->parse_tree->current_scope = prev_scope; |
550 | } break; | 556 | } break; |
@@ -554,7 +560,9 @@ symbol_check(Parser *parser, Node *node) { | |||
554 | node->scope = parser->parse_tree->current_scope; | 560 | node->scope = parser->parse_tree->current_scope; |
555 | for (size_t i = 0; i < array_size(node->block.expr); ++i) { | 561 | for (size_t i = 0; i < array_size(node->block.expr); ++i) { |
556 | Node *expr = node->block.expr[i]; | 562 | Node *expr = node->block.expr[i]; |
557 | symbol_check(parser, expr); | 563 | if (!symbol_check(parser, expr)) { |
564 | return false; | ||
565 | } | ||
558 | } | 566 | } |
559 | parser->parse_tree->current_scope = prev_scope; | 567 | parser->parse_tree->current_scope = prev_scope; |
560 | } break; | 568 | } break; |
@@ -585,6 +593,72 @@ symbol_check(Parser *parser, Node *node) { | |||
585 | } | 593 | } |
586 | 594 | ||
587 | bool | 595 | bool |
596 | resolve_typeclass(Parser *parser, Node *node) { | ||
597 | switch (node->type) { | ||
598 | case NODE_BUILTIN: { | ||
599 | switch (node->builtin.type) { | ||
600 | // Numbers. | ||
601 | case TOKEN_ADD: | ||
602 | case TOKEN_SUB: | ||
603 | case TOKEN_MUL: | ||
604 | case TOKEN_DIV: | ||
605 | case TOKEN_MOD: { node->type_class = TYPE_NUM; } break; | ||
606 | // Bools. | ||
607 | case TOKEN_NOT: | ||
608 | case TOKEN_AND: | ||
609 | case TOKEN_OR: | ||
610 | case TOKEN_EQ: | ||
611 | case TOKEN_LT: | ||
612 | case TOKEN_GT: | ||
613 | case TOKEN_LE: | ||
614 | case TOKEN_GE: { node->type_class = TYPE_BOOL; } break; | ||
615 | default: break; | ||
616 | } | ||
617 | for (size_t i = 0; i < array_size(node->builtin.args); ++i) { | ||
618 | Node *arg = node->builtin.args[i]; | ||
619 | resolve_typeclass(parser, arg); | ||
620 | } | ||
621 | } break; | ||
622 | case NODE_SYMBOL: { | ||
623 | // TODO: Resolve symbol type? | ||
624 | } break; | ||
625 | case NODE_FUN: { | ||
626 | // TODO: Resolve `node->type_class` based on the return value. | ||
627 | resolve_typeclass(parser, node->fun.body); | ||
628 | } break; | ||
629 | case NODE_BLOCK: { | ||
630 | for (size_t i = 0; i < array_size(node->block.expr); ++i) { | ||
631 | Node *expr = node->block.expr[i]; | ||
632 | resolve_typeclass(parser, expr); | ||
633 | } | ||
634 | Node *last_expr = node->block.expr[array_size(node->block.expr) - 1]; | ||
635 | node->type_class = last_expr->type_class; | ||
636 | } break; | ||
637 | case NODE_IF: { | ||
638 | node->type_class = TYPE_NONE; | ||
639 | resolve_typeclass(parser, node->ifexpr.cond); | ||
640 | resolve_typeclass(parser, node->ifexpr.expr_true); | ||
641 | if (node->ifexpr.expr_false != NULL) { | ||
642 | resolve_typeclass(parser, node->ifexpr.expr_false); | ||
643 | } | ||
644 | } break; | ||
645 | case NODE_SET: { | ||
646 | node->type_class = TYPE_NONE; | ||
647 | resolve_typeclass(parser, node->set.value); | ||
648 | } break; | ||
649 | case NODE_DEF: { | ||
650 | node->type_class = TYPE_NONE; | ||
651 | resolve_typeclass(parser, node->def.value); | ||
652 | } break; | ||
653 | case NODE_NUMBER: { node->type_class = TYPE_NUM; } break; | ||
654 | case NODE_BOOL: { node->type_class = TYPE_BOOL; } break; | ||
655 | case NODE_STRING: { node->type_class = TYPE_STRING; } break; | ||
656 | case NODE_TYPE: { node->type_class = TYPE_NONE; } break; | ||
657 | } | ||
658 | return true; | ||
659 | } | ||
660 | |||
661 | bool | ||
588 | semantic_analysis(Parser *parser) { | 662 | semantic_analysis(Parser *parser) { |
589 | // Fill up global function symbols. | 663 | // Fill up global function symbols. |
590 | for (size_t i = 0; i < array_size(parser->parse_tree->roots); ++i) { | 664 | for (size_t i = 0; i < array_size(parser->parse_tree->roots); ++i) { |
@@ -597,11 +671,16 @@ semantic_analysis(Parser *parser) { | |||
597 | } | 671 | } |
598 | } | 672 | } |
599 | 673 | ||
600 | // Fill up symbol tables in proper scope and check existance. | ||
601 | for (size_t i = 0; i < array_size(parser->parse_tree->roots); ++i) { | 674 | for (size_t i = 0; i < array_size(parser->parse_tree->roots); ++i) { |
675 | // Fill up symbol tables in proper scope and check existance. | ||
602 | symbol_check(parser, parser->parse_tree->roots[i]); | 676 | symbol_check(parser, parser->parse_tree->roots[i]); |
677 | // Resolve TypeClass for all elements. | ||
678 | resolve_typeclass(parser, parser->parse_tree->roots[i]); | ||
603 | } | 679 | } |
604 | 680 | ||
681 | // TODO: Resolve concrete types. | ||
682 | // TODO: Type check. | ||
683 | |||
605 | return true; | 684 | return true; |
606 | } | 685 | } |
607 | 686 | ||