aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-04-07 12:41:34 -0300
committerBad Diode <bd@badd10de.dev>2022-04-07 12:41:34 -0300
commit9f934cbc0f0fd60a6938ac1c4c84edc270de94ca (patch)
tree9304f9bc802eac175b594de4bf81730b7d815513 /src
parenta718a62a45b081bfd2cff8da56da2d2856ca244b (diff)
downloadbdl-9f934cbc0f0fd60a6938ac1c4c84edc270de94ca.tar.gz
bdl-9f934cbc0f0fd60a6938ac1c4c84edc270de94ca.zip
Add initial implementation of typeclass resolution
Diffstat (limited to 'src')
-rw-r--r--src/nodes.c1
-rw-r--r--src/nodes.h9
-rw-r--r--src/parser.c89
3 files changed, 94 insertions, 5 deletions
diff --git a/src/nodes.c b/src/nodes.c
index a5b67d1..5689d18 100644
--- a/src/nodes.c
+++ b/src/nodes.c
@@ -9,6 +9,7 @@ alloc_node(NodeType type) {
9 node->line = 0; 9 node->line = 0;
10 node->col = 0; 10 node->col = 0;
11 node->scope = NULL; 11 node->scope = NULL;
12 node->type_class = TYPE_UNK;
12 return node; 13 return node;
13} 14}
14 15
diff --git a/src/nodes.h b/src/nodes.h
index acbe19e..853495a 100644
--- a/src/nodes.h
+++ b/src/nodes.h
@@ -15,11 +15,20 @@ typedef enum NodeType {
15 NODE_IF, 15 NODE_IF,
16} NodeType; 16} NodeType;
17 17
18typedef enum TypeClass {
19 TYPE_UNK,
20 TYPE_NONE,
21 TYPE_NUM,
22 TYPE_BOOL,
23 TYPE_STRING,
24} TypeClass;
25
18typedef struct Node { 26typedef struct Node {
19 NodeType type; 27 NodeType type;
20 size_t line; 28 size_t line;
21 size_t col; 29 size_t col;
22 struct Scope *scope; 30 struct Scope *scope;
31 TypeClass type_class;
23 32
24 union { 33 union {
25 // Numbers. 34 // Numbers.
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
587bool 595bool
596resolve_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
661bool
588semantic_analysis(Parser *parser) { 662semantic_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