aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-04-11 18:39:27 -0300
committerBad Diode <bd@badd10de.dev>2022-04-11 18:39:27 -0300
commit140cd959daabf5c18b9cccc210a58ab50351e884 (patch)
treeff8480fc271d520463f8be4a344f63fb037fffed /src
parentab3e064c6f90ec94daad99b5a4c56e0abbcc79bb (diff)
downloadbdl-140cd959daabf5c18b9cccc210a58ab50351e884.tar.gz
bdl-140cd959daabf5c18b9cccc210a58ab50351e884.zip
Add funcall node type and fix type resolution bugs
Diffstat (limited to 'src')
-rw-r--r--src/main.c1
-rw-r--r--src/nodes.c15
-rw-r--r--src/nodes.h7
-rw-r--r--src/parser.c92
-rw-r--r--src/viz.c13
5 files changed, 116 insertions, 12 deletions
diff --git a/src/main.c b/src/main.c
index a0d26d0..863d9d1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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
18typedef struct Node { 19typedef 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
236Node * 236Node *
237parse_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
264Node *
237parse_def(Parser *parser) { 265parse_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
423Node * 450Node *
@@ -518,6 +545,10 @@ alloc_parsetree(void) {
518bool 545bool
519parse_roots(Parser *parser) { 546parse_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;
diff --git a/src/viz.c b/src/viz.c
index 8b5d4cf..81cc1ff 100644
--- a/src/viz.c
+++ b/src/viz.c
@@ -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
15void 16void
@@ -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