diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 56 |
1 files changed, 55 insertions, 1 deletions
@@ -75,12 +75,14 @@ typedef enum NodeKind { | |||
75 | NODE_LET, | 75 | NODE_LET, |
76 | NODE_SET, | 76 | NODE_SET, |
77 | NODE_STRUCT, | 77 | NODE_STRUCT, |
78 | NODE_IF, | ||
78 | // Helpers. | 79 | // Helpers. |
79 | NODE_SYMBOL_IDX, | 80 | NODE_SYMBOL_IDX, |
80 | NODE_TYPE, | 81 | NODE_TYPE, |
81 | NODE_ARR_TYPE, | 82 | NODE_ARR_TYPE, |
82 | NODE_COMPOUND_TYPE, | 83 | NODE_COMPOUND_TYPE, |
83 | NODE_STRUCT_FIELD, | 84 | NODE_STRUCT_FIELD, |
85 | NODE_BLOCK, | ||
84 | } NodeKind; | 86 | } NodeKind; |
85 | 87 | ||
86 | Str node_str[] = { | 88 | Str node_str[] = { |
@@ -120,12 +122,14 @@ Str node_str[] = { | |||
120 | [NODE_LET] = cstr("LET"), | 122 | [NODE_LET] = cstr("LET"), |
121 | [NODE_SET] = cstr("SET"), | 123 | [NODE_SET] = cstr("SET"), |
122 | [NODE_STRUCT] = cstr("STRUCT DEF"), | 124 | [NODE_STRUCT] = cstr("STRUCT DEF"), |
125 | [NODE_IF] = cstr("IF"), | ||
123 | // Helpers. | 126 | // Helpers. |
124 | [NODE_TYPE] = cstr("TYPE"), | 127 | [NODE_TYPE] = cstr("TYPE"), |
125 | [NODE_ARR_TYPE] = cstr("TYPE (ARR)"), | 128 | [NODE_ARR_TYPE] = cstr("TYPE (ARR)"), |
126 | [NODE_SYMBOL_IDX] = cstr("SYMBOL[IDX]"), | 129 | [NODE_SYMBOL_IDX] = cstr("SYMBOL[IDX]"), |
127 | [NODE_COMPOUND_TYPE] = cstr("TYPE (COMPOUND)"), | 130 | [NODE_COMPOUND_TYPE] = cstr("TYPE (COMPOUND)"), |
128 | [NODE_STRUCT_FIELD] = cstr("FIELD"), | 131 | [NODE_STRUCT_FIELD] = cstr("FIELD"), |
132 | [NODE_BLOCK] = cstr("BLOCK"), | ||
129 | }; | 133 | }; |
130 | 134 | ||
131 | typedef struct Node { | 135 | typedef struct Node { |
@@ -156,12 +160,18 @@ typedef struct Node { | |||
156 | struct Node *var_val; | 160 | struct Node *var_val; |
157 | }; | 161 | }; |
158 | struct { | 162 | struct { |
163 | struct Node *cond_if; | ||
164 | struct Node *cond_expr; | ||
165 | struct Node *cond_else; | ||
166 | }; | ||
167 | struct { | ||
159 | struct Node *field_name; | 168 | struct Node *field_name; |
160 | struct Node *field_type; | 169 | struct Node *field_type; |
161 | struct Node *field_val; | 170 | struct Node *field_val; |
162 | }; | 171 | }; |
163 | struct Node **struct_field; | 172 | struct Node **struct_field; |
164 | struct Node **elements; | 173 | struct Node **elements; |
174 | struct Node **statements; | ||
165 | }; | 175 | }; |
166 | bool is_ptr; | 176 | bool is_ptr; |
167 | } Node; | 177 | } Node; |
@@ -222,10 +232,11 @@ void parse_string(Parser *parser); | |||
222 | void parse_symbol(Parser *parser); | 232 | void parse_symbol(Parser *parser); |
223 | void parse_keyword(Parser *parser); | 233 | void parse_keyword(Parser *parser); |
224 | void parse_type(Parser *parser); | 234 | void parse_type(Parser *parser); |
235 | void parse_block(Parser *parser); | ||
225 | 236 | ||
226 | ParseRule parse_rules[] = { | 237 | ParseRule parse_rules[] = { |
227 | [TOK_LPAREN] = {parse_grouping, NULL, PREC_NONE}, | 238 | [TOK_LPAREN] = {parse_grouping, NULL, PREC_NONE}, |
228 | [TOK_LCURLY] = {NULL, NULL, PREC_NONE}, | 239 | [TOK_LCURLY] = {parse_block, NULL, PREC_NONE}, |
229 | [TOK_AT] = {parse_symbol, NULL, PREC_NONE}, | 240 | [TOK_AT] = {parse_symbol, NULL, PREC_NONE}, |
230 | 241 | ||
231 | // Arithmetic. | 242 | // Arithmetic. |
@@ -334,6 +345,22 @@ parse_consume(Parser *parser, TokenKind kind, Str msg) { | |||
334 | parse_emit_err(parser, parser->current, msg); | 345 | parse_emit_err(parser, parser->current, msg); |
335 | } | 346 | } |
336 | 347 | ||
348 | void | ||
349 | parse_block(Parser *parser) { | ||
350 | #if DEBUG == 1 | ||
351 | print("parsing block "); | ||
352 | print_token(prev); | ||
353 | #endif | ||
354 | Node *block = node_alloc(parser, NODE_BLOCK, parser->previous); | ||
355 | if (!block) return; | ||
356 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | ||
357 | parse_expr(parser, PREC_LOW); | ||
358 | Node *next = array_pop(parser->nodes); | ||
359 | array_push(block->statements, next, parser->storage); | ||
360 | } | ||
361 | array_push(parser->nodes, block, parser->storage); | ||
362 | } | ||
363 | |||
337 | void | 364 | void |
338 | parse_expr(Parser *parser, ParsePrecedence precedence) { | 365 | parse_expr(Parser *parser, ParsePrecedence precedence) { |
339 | parse_advance(parser); | 366 | parse_advance(parser); |
@@ -524,6 +551,18 @@ parse_keyword(Parser *parser) { | |||
524 | array_push(node->struct_field, field, parser->storage); | 551 | array_push(node->struct_field, field, parser->storage); |
525 | } | 552 | } |
526 | } break; | 553 | } break; |
554 | case TOK_IF: { | ||
555 | node = node_alloc(parser, NODE_IF, prev); | ||
556 | if (!node) return; | ||
557 | parse_expr(parser, PREC_LOW); | ||
558 | node->cond_if = array_pop(parser->nodes); | ||
559 | parse_expr(parser, PREC_LOW); | ||
560 | node->cond_expr = array_pop(parser->nodes); | ||
561 | if (parse_match(parser, TOK_ELSE)) { | ||
562 | parse_expr(parser, PREC_LOW); | ||
563 | node->cond_else = array_pop(parser->nodes); | ||
564 | } | ||
565 | } break; | ||
527 | default: return; // Unreachable. | 566 | default: return; // Unreachable. |
528 | } | 567 | } |
529 | array_push(parser->nodes, node, parser->storage); | 568 | array_push(parser->nodes, node, parser->storage); |
@@ -731,6 +770,7 @@ graph_node(Node *node) { | |||
731 | println("\"];"); | 770 | println("\"];"); |
732 | 771 | ||
733 | switch (node->kind) { | 772 | switch (node->kind) { |
773 | case NODE_BLOCK: | ||
734 | case NODE_STRUCT_LIT: | 774 | case NODE_STRUCT_LIT: |
735 | case NODE_COMPOUND_TYPE: { | 775 | case NODE_COMPOUND_TYPE: { |
736 | for (sz i = 0; i < array_size(node->elements); i++) { | 776 | for (sz i = 0; i < array_size(node->elements); i++) { |
@@ -746,6 +786,20 @@ graph_node(Node *node) { | |||
746 | graph_node(next); | 786 | graph_node(next); |
747 | } | 787 | } |
748 | } break; | 788 | } break; |
789 | case NODE_IF: { | ||
790 | if (node->cond_if) { | ||
791 | println("%d:e->%d:w;", node->id, node->cond_if->id); | ||
792 | graph_node(node->cond_if); | ||
793 | } | ||
794 | if (node->cond_expr) { | ||
795 | println("%d:e->%d:w;", node->id, node->cond_expr->id); | ||
796 | graph_node(node->cond_expr); | ||
797 | } | ||
798 | if (node->cond_else) { | ||
799 | println("%d:e->%d:w;", node->id, node->cond_else->id); | ||
800 | graph_node(node->cond_else); | ||
801 | } | ||
802 | } break; | ||
749 | case NODE_STRUCT_FIELD: | 803 | case NODE_STRUCT_FIELD: |
750 | case NODE_SET: | 804 | case NODE_SET: |
751 | case NODE_LET: { | 805 | case NODE_LET: { |