diff options
author | Bad Diode <bd@badd10de.dev> | 2022-04-11 18:39:27 -0300 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2022-04-11 18:39:27 -0300 |
commit | 140cd959daabf5c18b9cccc210a58ab50351e884 (patch) | |
tree | ff8480fc271d520463f8be4a344f63fb037fffed /src | |
parent | ab3e064c6f90ec94daad99b5a4c56e0abbcc79bb (diff) | |
download | bdl-140cd959daabf5c18b9cccc210a58ab50351e884.tar.gz bdl-140cd959daabf5c18b9cccc210a58ab50351e884.zip |
Add funcall node type and fix type resolution bugs
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 1 | ||||
-rw-r--r-- | src/nodes.c | 15 | ||||
-rw-r--r-- | src/nodes.h | 7 | ||||
-rw-r--r-- | src/parser.c | 92 | ||||
-rw-r--r-- | src/viz.c | 13 |
5 files changed, 116 insertions, 12 deletions
@@ -26,6 +26,7 @@ process_source(const StringView *source, const char *file_name) { | |||
26 | // Read tokens. | 26 | // Read tokens. |
27 | Token *tokens = tokenize(source); | 27 | Token *tokens = tokenize(source); |
28 | check_errors(file_name); | 28 | check_errors(file_name); |
29 | // print_tokens(tokens); | ||
29 | 30 | ||
30 | // Parser. | 31 | // Parser. |
31 | ParseTree *parse_tree = parse(tokens); | 32 | ParseTree *parse_tree = parse(tokens); |
diff --git a/src/nodes.c b/src/nodes.c index 51cc9ef..b8a5f09 100644 --- a/src/nodes.c +++ b/src/nodes.c | |||
@@ -114,6 +114,21 @@ print_node(Node *node) { | |||
114 | print_node(node->fun.body); | 114 | print_node(node->fun.body); |
115 | printf(")"); | 115 | printf(")"); |
116 | } break; | 116 | } break; |
117 | case NODE_FUNCALL: { | ||
118 | printf("("); | ||
119 | print_node(node->funcall.name); | ||
120 | size_t n_args = array_size(node->funcall.args); | ||
121 | if (n_args != 0) { | ||
122 | printf(" "); | ||
123 | } | ||
124 | for (size_t i = 0; i < n_args; ++i) { | ||
125 | print_node(node->funcall.args[i]); | ||
126 | if (i < n_args - 1) { | ||
127 | printf(" "); | ||
128 | } | ||
129 | } | ||
130 | printf(")"); | ||
131 | } break; | ||
117 | default: { printf("{#unknown#}"); } break; | 132 | default: { printf("{#unknown#}"); } break; |
118 | } | 133 | } |
119 | } | 134 | } |
diff --git a/src/nodes.h b/src/nodes.h index 52022cc..11b30dd 100644 --- a/src/nodes.h +++ b/src/nodes.h | |||
@@ -13,6 +13,7 @@ typedef enum NodeType { | |||
13 | NODE_FUN, | 13 | NODE_FUN, |
14 | NODE_BLOCK, | 14 | NODE_BLOCK, |
15 | NODE_IF, | 15 | NODE_IF, |
16 | NODE_FUNCALL, | ||
16 | } NodeType; | 17 | } NodeType; |
17 | 18 | ||
18 | typedef struct Node { | 19 | typedef struct Node { |
@@ -43,6 +44,12 @@ typedef struct Node { | |||
43 | struct Node **args; | 44 | struct Node **args; |
44 | } builtin; | 45 | } builtin; |
45 | 46 | ||
47 | // Function call. | ||
48 | struct { | ||
49 | struct Node *name; | ||
50 | struct Node **args; | ||
51 | } funcall; | ||
52 | |||
46 | // Variable definition. | 53 | // Variable definition. |
47 | struct { | 54 | struct { |
48 | struct Node *symbol; | 55 | struct Node *symbol; |
diff --git a/src/parser.c b/src/parser.c index 252ceaa..92f7654 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -234,6 +234,34 @@ parse_builtin(Parser *parser) { | |||
234 | } | 234 | } |
235 | 235 | ||
236 | Node * | 236 | Node * |
237 | parse_funcall(Parser *parser) { | ||
238 | Token tok = peek_token(parser); | ||
239 | Node *name = parse_symbol(parser); | ||
240 | if (name == NULL) { | ||
241 | return NULL; | ||
242 | } | ||
243 | Node *node = alloc_node(NODE_FUNCALL); | ||
244 | node->funcall.name = name; | ||
245 | node->line = tok.line; | ||
246 | node->col = tok.col; | ||
247 | array_init(node->funcall.args, 0); | ||
248 | while (has_next(parser)) { | ||
249 | Token next = peek_token(parser); | ||
250 | if (next.type == TOKEN_RPAREN) { | ||
251 | next_token(parser); | ||
252 | return node; | ||
253 | } | ||
254 | Node *arg = parse_next(parser); | ||
255 | if (arg == NULL) { | ||
256 | break; | ||
257 | } | ||
258 | array_push(node->funcall.args, arg); | ||
259 | } | ||
260 | push_error(ERR_TYPE_PARSER, ERR_UNMATCHED_PAREN, tok.line, tok.col); | ||
261 | return NULL; | ||
262 | } | ||
263 | |||
264 | Node * | ||
237 | parse_def(Parser *parser) { | 265 | parse_def(Parser *parser) { |
238 | Token tok = next_token(parser); | 266 | Token tok = next_token(parser); |
239 | 267 | ||
@@ -416,8 +444,7 @@ parse_paren(Parser *parser) { | |||
416 | default: break; | 444 | default: break; |
417 | } | 445 | } |
418 | 446 | ||
419 | push_error(ERR_TYPE_PARSER, ERR_UNIMPLEMENTED, tok.line, tok.col); | 447 | return parse_funcall(parser); |
420 | return NULL; | ||
421 | } | 448 | } |
422 | 449 | ||
423 | Node * | 450 | Node * |
@@ -518,6 +545,10 @@ alloc_parsetree(void) { | |||
518 | bool | 545 | bool |
519 | parse_roots(Parser *parser) { | 546 | parse_roots(Parser *parser) { |
520 | while (has_next(parser)) { | 547 | while (has_next(parser)) { |
548 | Token tok = peek_token(parser); | ||
549 | if (tok.type == TOKEN_EOF) { | ||
550 | break; | ||
551 | } | ||
521 | Node *node = parse_next(parser); | 552 | Node *node = parse_next(parser); |
522 | if (node == NULL) { | 553 | if (node == NULL) { |
523 | return false; | 554 | return false; |
@@ -679,6 +710,11 @@ symbol_check(Parser *parser, Node *node) { | |||
679 | return false; | 710 | return false; |
680 | } | 711 | } |
681 | } break; | 712 | } break; |
713 | case NODE_FUNCALL: { | ||
714 | if (!symbol_check(parser, node->funcall.name)) { | ||
715 | return false; | ||
716 | } | ||
717 | } break; | ||
682 | default: break; | 718 | default: break; |
683 | } | 719 | } |
684 | return true; | 720 | return true; |
@@ -799,7 +835,9 @@ resolve_type(Parser *parser, Node *node) { | |||
799 | case NODE_BUILTIN: { | 835 | case NODE_BUILTIN: { |
800 | for (size_t i = 0; i < array_size(node->builtin.args); ++i) { | 836 | for (size_t i = 0; i < array_size(node->builtin.args); ++i) { |
801 | Node *arg = node->builtin.args[i]; | 837 | Node *arg = node->builtin.args[i]; |
802 | resolve_type(parser, arg); | 838 | if (!resolve_type(parser, arg)) { |
839 | return false; | ||
840 | } | ||
803 | } | 841 | } |
804 | switch (node->builtin.type) { | 842 | switch (node->builtin.type) { |
805 | // Numbers. | 843 | // Numbers. |
@@ -865,7 +903,9 @@ resolve_type(Parser *parser, Node *node) { | |||
865 | node->expr_type = find_symbol(parser, node); | 903 | node->expr_type = find_symbol(parser, node); |
866 | } break; | 904 | } break; |
867 | case NODE_FUN: { | 905 | case NODE_FUN: { |
868 | resolve_type(parser, node->fun.body); | 906 | if (!resolve_type(parser, node->fun.body)) { |
907 | return false; | ||
908 | } | ||
869 | // Check that the type of body matches the return type. | 909 | // Check that the type of body matches the return type. |
870 | StringView *type_body = &node->fun.body->expr_type->name; | 910 | StringView *type_body = &node->fun.body->expr_type->name; |
871 | StringView *return_type = &node->fun.return_type->string; | 911 | StringView *return_type = &node->fun.return_type->string; |
@@ -877,18 +917,26 @@ resolve_type(Parser *parser, Node *node) { | |||
877 | case NODE_BLOCK: { | 917 | case NODE_BLOCK: { |
878 | for (size_t i = 0; i < array_size(node->block.expr); ++i) { | 918 | for (size_t i = 0; i < array_size(node->block.expr); ++i) { |
879 | Node *expr = node->block.expr[i]; | 919 | Node *expr = node->block.expr[i]; |
880 | resolve_type(parser, expr); | 920 | if (!resolve_type(parser, expr)) { |
921 | return false; | ||
922 | } | ||
881 | } | 923 | } |
882 | Node *last_expr = node->block.expr[array_size(node->block.expr) - 1]; | 924 | Node *last_expr = node->block.expr[array_size(node->block.expr) - 1]; |
883 | node->expr_type = last_expr->expr_type; | 925 | node->expr_type = last_expr->expr_type; |
884 | } break; | 926 | } break; |
885 | case NODE_IF: { | 927 | case NODE_IF: { |
886 | resolve_type(parser, node->ifexpr.cond); | 928 | if (!resolve_type(parser, node->ifexpr.cond)) { |
887 | resolve_type(parser, node->ifexpr.expr_true); | 929 | return false; |
930 | } | ||
931 | if (!resolve_type(parser, node->ifexpr.expr_true)) { | ||
932 | return false; | ||
933 | } | ||
888 | Type *type_true = node->ifexpr.expr_true->expr_type; | 934 | Type *type_true = node->ifexpr.expr_true->expr_type; |
889 | node->expr_type = type_true; | 935 | node->expr_type = type_true; |
890 | if (node->ifexpr.expr_false != NULL) { | 936 | if (node->ifexpr.expr_false != NULL) { |
891 | resolve_type(parser, node->ifexpr.expr_false); | 937 | if (!resolve_type(parser, node->ifexpr.expr_false)) { |
938 | return false; | ||
939 | } | ||
892 | } | 940 | } |
893 | 941 | ||
894 | // Check ifexpr.cond is a bool. | 942 | // Check ifexpr.cond is a bool. |
@@ -913,11 +961,15 @@ resolve_type(Parser *parser, Node *node) { | |||
913 | } break; | 961 | } break; |
914 | case NODE_SET: { | 962 | case NODE_SET: { |
915 | node->expr_type = &default_types[TYPE_VOID]; | 963 | node->expr_type = &default_types[TYPE_VOID]; |
916 | resolve_type(parser, node->set.value); | 964 | if (!resolve_type(parser, node->set.value)) { |
965 | return false; | ||
966 | } | ||
917 | } break; | 967 | } break; |
918 | case NODE_DEF: { | 968 | case NODE_DEF: { |
919 | node->expr_type = &default_types[TYPE_VOID]; | 969 | node->expr_type = &default_types[TYPE_VOID]; |
920 | resolve_type(parser, node->def.value); | 970 | if (!resolve_type(parser, node->def.value)) { |
971 | return false; | ||
972 | } | ||
921 | } break; | 973 | } break; |
922 | case NODE_NUMBER: { | 974 | case NODE_NUMBER: { |
923 | if (node->number.fractional != 0) { | 975 | if (node->number.fractional != 0) { |
@@ -934,6 +986,18 @@ resolve_type(Parser *parser, Node *node) { | |||
934 | case NODE_STRING: { | 986 | case NODE_STRING: { |
935 | node->expr_type = &default_types[TYPE_STR]; | 987 | node->expr_type = &default_types[TYPE_STR]; |
936 | } break; | 988 | } break; |
989 | case NODE_FUNCALL: { | ||
990 | if (!resolve_type(parser, node->funcall.name)) { | ||
991 | return false; | ||
992 | } | ||
993 | node->expr_type = node->funcall.name->expr_type; | ||
994 | for (size_t i = 0; i < array_size(node->funcall.args); ++i) { | ||
995 | Node *arg = node->funcall.args[i]; | ||
996 | if (!resolve_type(parser, arg)) { | ||
997 | return false; | ||
998 | } | ||
999 | } | ||
1000 | } break; | ||
937 | default: break; | 1001 | default: break; |
938 | } | 1002 | } |
939 | if (node->scope != NULL) { | 1003 | if (node->scope != NULL) { |
@@ -960,9 +1024,13 @@ semantic_analysis(Parser *parser) { | |||
960 | 1024 | ||
961 | for (size_t i = 0; i < array_size(parser->parse_tree->roots); ++i) { | 1025 | for (size_t i = 0; i < array_size(parser->parse_tree->roots); ++i) { |
962 | // Fill up symbol tables in proper scope and check existance. | 1026 | // Fill up symbol tables in proper scope and check existance. |
963 | symbol_check(parser, parser->parse_tree->roots[i]); | 1027 | if (!symbol_check(parser, parser->parse_tree->roots[i])) { |
1028 | return false; | ||
1029 | } | ||
964 | // Resolve type of expression for all elements. | 1030 | // Resolve type of expression for all elements. |
965 | resolve_type(parser, parser->parse_tree->roots[i]); | 1031 | if (!resolve_type(parser, parser->parse_tree->roots[i])) { |
1032 | return false; | ||
1033 | } | ||
966 | } | 1034 | } |
967 | 1035 | ||
968 | return true; | 1036 | return true; |
@@ -10,6 +10,7 @@ static const char* node_str[] = { | |||
10 | [NODE_FUN] = "FUN", | 10 | [NODE_FUN] = "FUN", |
11 | [NODE_BLOCK] = "BLOCK", | 11 | [NODE_BLOCK] = "BLOCK", |
12 | [NODE_IF] = "IF", | 12 | [NODE_IF] = "IF", |
13 | [NODE_FUNCALL] = "FUNCALL", | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | void | 16 | void |
@@ -135,6 +136,18 @@ viz_node(Node *node) { | |||
135 | viz_node(node->fun.body); | 136 | viz_node(node->fun.body); |
136 | printf("%zu:bod:e->%zu:top:w;\n", node->id, node->fun.body->id); | 137 | printf("%zu:bod:e->%zu:top:w;\n", node->id, node->fun.body->id); |
137 | } break; | 138 | } break; |
139 | case NODE_FUNCALL: { | ||
140 | printf(" | Name: "); | ||
141 | sv_write(&node->funcall.name->string); | ||
142 | printf(" | <args> Args: "); | ||
143 | printf("\"];\n"); | ||
144 | size_t n_args = array_size(node->funcall.args); | ||
145 | for (size_t i = 0; i < n_args; ++i) { | ||
146 | viz_node(node->funcall.args[i]); | ||
147 | printf("%zu:args:e->%zu:top:w;\n", node->id, | ||
148 | node->funcall.args[i]->id); | ||
149 | } | ||
150 | } break; | ||
138 | } | 151 | } |
139 | } | 152 | } |
140 | 153 | ||