aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-20 14:20:24 +0200
committerBad Diode <bd@badd10de.dev>2024-06-20 14:20:24 +0200
commiteca9cb305b08e0e292d01008797b9300d47f72d5 (patch)
tree0fd1131586e457ee92325f078033404c0fe7caec /src/parser.c
parent972c453a085bedb3de8d598cc4ae4486e24f0144 (diff)
downloadbdl-eca9cb305b08e0e292d01008797b9300d47f72d5.tar.gz
bdl-eca9cb305b08e0e292d01008797b9300d47f72d5.zip
Add parsing support for functions
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/parser.c b/src/parser.c
index 84f3424..dbab4af 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -53,6 +53,11 @@ typedef enum NodeKind {
53 NODE_BREAK, 53 NODE_BREAK,
54 NODE_CONTINUE, 54 NODE_CONTINUE,
55 NODE_WHILE, 55 NODE_WHILE,
56 // Functions.
57 NODE_FUN,
58 NODE_FUN_PARAM,
59 NODE_FUNCALL,
60 NODE_RETURN,
56 // Helpers. 61 // Helpers.
57 NODE_SYMBOL_IDX, 62 NODE_SYMBOL_IDX,
58 NODE_TYPE, 63 NODE_TYPE,
@@ -95,6 +100,11 @@ Str node_str[] = {
95 [NODE_FALSE] = cstr("FALSE"), 100 [NODE_FALSE] = cstr("FALSE"),
96 [NODE_NIL] = cstr("NIL"), 101 [NODE_NIL] = cstr("NIL"),
97 [NODE_STRUCT_LIT] = cstr("STRUCT LIT"), 102 [NODE_STRUCT_LIT] = cstr("STRUCT LIT"),
103 // Functions.
104 [NODE_FUN] = cstr("FUNCTION"),
105 [NODE_FUN_PARAM] = cstr("PARAM"),
106 [NODE_FUNCALL] = cstr("FUNCALL"),
107 [NODE_RETURN] = cstr("RETURN"),
98 // Keywords. 108 // Keywords.
99 [NODE_LET] = cstr("LET"), 109 [NODE_LET] = cstr("LET"),
100 [NODE_SET] = cstr("SET"), 110 [NODE_SET] = cstr("SET"),
@@ -158,6 +168,10 @@ typedef struct Node {
158 struct Node *field_val; 168 struct Node *field_val;
159 }; 169 };
160 struct { 170 struct {
171 struct Node *param_name;
172 struct Node *param_type;
173 };
174 struct {
161 struct Node *match_expr; 175 struct Node *match_expr;
162 struct Node **match_cases; 176 struct Node **match_cases;
163 }; 177 };
@@ -168,6 +182,13 @@ typedef struct Node {
168 struct Node **struct_field; 182 struct Node **struct_field;
169 struct Node **elements; 183 struct Node **elements;
170 struct Node **statements; 184 struct Node **statements;
185 struct Node **expressions;
186 struct {
187 struct Node *func_name;
188 struct Node **func_params;
189 struct Node **func_ret;
190 struct Node *func_body;
191 };
171 }; 192 };
172 bool is_ptr; 193 bool is_ptr;
173} Node; 194} Node;
@@ -671,6 +692,107 @@ parse_keyword(Parser *parser) {
671 parse_expr(parser, PREC_LOW); 692 parse_expr(parser, PREC_LOW);
672 node->while_expr = array_pop(parser->nodes); 693 node->while_expr = array_pop(parser->nodes);
673 } break; 694 } break;
695 case TOK_FUN: {
696 node = node_alloc(parser, NODE_FUN, prev);
697 if (!node) return;
698 parse_consume(parser, TOK_SYMBOL, cstr("expected function name"));
699 parse_consume(parser, TOK_LPAREN,
700 cstr("expected '(' on function definition"));
701 // Parameters.
702 while (!parse_match(parser, TOK_RPAREN) && !parser->panic) {
703 Node *param =
704 node_alloc(parser, NODE_FUN_PARAM, parser->current);
705 if (!param) return;
706 Node *name = node_alloc(parser, NODE_SYMBOL, prev);
707 if (!name) return;
708 parse_consume(parser, TOK_SYMBOL, cstr("expected symbol name"));
709 name->value.sym = parser->previous.val;
710 param->param_name = name;
711
712 Node *type = node_alloc(parser, NODE_TYPE, prev);
713 if (!type) return;
714 parse_consume(parser, TOK_COLON, cstr("expected param type"));
715 if (parse_match(parser, TOK_AT)) {
716 type->is_ptr = true;
717 }
718 parse_consume(parser, TOK_SYMBOL, cstr("expected param type"));
719 type->value.sym = parser->previous.val;
720 param->param_type = type;
721 if (parse_match(parser, TOK_LSQUARE)) {
722 type->kind = NODE_ARR_TYPE,
723 parse_consume(parser, TOK_NUM_INT,
724 cstr("no array size given"));
725 parse_number(parser);
726 type->arr_size = array_pop(parser->nodes);
727 parse_consume(parser, TOK_RSQUARE,
728 cstr("unmatched brackets ']' in array type"));
729 }
730 array_push(node->func_params, param, parser->storage);
731 }
732 parse_consume(parser, TOK_COLON, cstr("expected param type"));
733
734 // Return type(s).
735 if (!parse_match(parser, TOK_NIL)) {
736 if (parse_match(parser, TOK_LPAREN)) {
737 while (!parse_match(parser, TOK_RPAREN) && !parser->panic) {
738 Node *ret = node_alloc(parser, NODE_TYPE, prev);
739 if (!ret) return;
740 if (parse_match(parser, TOK_AT)) {
741 ret->is_ptr = true;
742 }
743 parse_consume(parser, TOK_SYMBOL,
744 cstr("expected type name"));
745 ret->value.sym = parser->previous.val;
746 if (parse_match(parser, TOK_LSQUARE)) {
747 ret->kind = NODE_ARR_TYPE,
748 parse_consume(parser, TOK_NUM_INT,
749 cstr("no array size given"));
750 parse_number(parser);
751 ret->arr_size = array_pop(parser->nodes);
752 parse_consume(
753 parser, TOK_RSQUARE,
754 cstr("unmatched brackets ']' in array type"));
755 }
756 array_push(node->func_ret, ret, parser->storage);
757 }
758 } else {
759 Node *ret = node_alloc(parser, NODE_TYPE, prev);
760 if (!ret) return;
761 if (parse_match(parser, TOK_AT)) {
762 ret->is_ptr = true;
763 }
764 parse_consume(parser, TOK_SYMBOL,
765 cstr("expected type name"));
766 ret->value.sym = parser->previous.val;
767 if (parse_match(parser, TOK_LSQUARE)) {
768 ret->kind = NODE_ARR_TYPE,
769 parse_consume(parser, TOK_NUM_INT,
770 cstr("no array size given"));
771 parse_number(parser);
772 ret->arr_size = array_pop(parser->nodes);
773 parse_consume(
774 parser, TOK_RSQUARE,
775 cstr("unmatched brackets ']' in array type"));
776 }
777 array_push(node->func_ret, ret, parser->storage);
778 }
779 }
780
781 // Body.
782 parse_expr(parser, PREC_LOW);
783 node->func_body = array_pop(parser->nodes);
784 } break;
785 case TOK_RETURN: {
786 node = node_alloc(parser, NODE_RETURN, prev);
787 if (!node) return;
788 parse_consume(parser, TOK_LPAREN,
789 cstr("expected '(' after return"));
790 while (!parse_match(parser, TOK_RPAREN) && !parser->panic) {
791 parse_expr(parser, PREC_LOW);
792 array_push(node->expressions, array_pop(parser->nodes),
793 parser->storage);
794 }
795 } break;
674 default: return; // Unreachable. 796 default: return; // Unreachable.
675 } 797 }
676 array_push(parser->nodes, node, parser->storage); 798 array_push(parser->nodes, node, parser->storage);
@@ -865,6 +987,7 @@ graph_node(Node *node) {
865 case NODE_STRUCT: 987 case NODE_STRUCT:
866 case NODE_STRUCT_LIT: print("| Name: %s", node->value.sym); break; 988 case NODE_STRUCT_LIT: print("| Name: %s", node->value.sym); break;
867 case NODE_SYMBOL: 989 case NODE_SYMBOL:
990 case NODE_ARR_TYPE:
868 case NODE_TYPE: { 991 case NODE_TYPE: {
869 if (node->is_ptr) { 992 if (node->is_ptr) {
870 print("| Name: @%s", node->value.sym); 993 print("| Name: @%s", node->value.sym);
@@ -877,6 +1000,26 @@ graph_node(Node *node) {
877 println("\"];"); 1000 println("\"];");
878 1001
879 switch (node->kind) { 1002 switch (node->kind) {
1003 case NODE_FUN: {
1004 for (sz i = 0; i < array_size(node->func_params); i++) {
1005 Node *next = node->func_params[i];
1006 println("%d:e->%d:w;", node->id, next->id);
1007 graph_node(next);
1008 }
1009 for (sz i = 0; i < array_size(node->func_ret); i++) {
1010 Node *next = node->func_ret[i];
1011 println("%d:e->%d:w;", node->id, next->id);
1012 graph_node(next);
1013 }
1014 if (node->func_name) {
1015 println("%d:e->%d:w;", node->id, node->func_name->id);
1016 graph_node(node->func_name);
1017 }
1018 if (node->func_body) {
1019 println("%d:e->%d:w;", node->id, node->func_body->id);
1020 graph_node(node->func_body);
1021 }
1022 } break;
880 case NODE_COND: 1023 case NODE_COND:
881 case NODE_MATCH: { 1024 case NODE_MATCH: {
882 if (node->match_expr) { 1025 if (node->match_expr) {
@@ -889,6 +1032,7 @@ graph_node(Node *node) {
889 graph_node(next); 1032 graph_node(next);
890 } 1033 }
891 } break; 1034 } break;
1035 case NODE_RETURN:
892 case NODE_BLOCK: 1036 case NODE_BLOCK:
893 case NODE_STRUCT_LIT: 1037 case NODE_STRUCT_LIT:
894 case NODE_COMPOUND_TYPE: { 1038 case NODE_COMPOUND_TYPE: {