diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-18 19:47:39 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-18 19:47:39 +0200 |
commit | f9d0fe5ad641e453724dabc2b17634a44e198ce0 (patch) | |
tree | 9d86cd3f89b36ae9053a383fd44f93f9c044b0fe /src/main.c | |
parent | c9db27abbbfa80a79515e26efaae9012d3275404 (diff) | |
download | bdl-f9d0fe5ad641e453724dabc2b17634a44e198ce0.tar.gz bdl-f9d0fe5ad641e453724dabc2b17634a44e198ce0.zip |
Add enum parsing
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 55 |
1 files changed, 46 insertions, 9 deletions
@@ -78,12 +78,14 @@ typedef enum NodeKind { | |||
78 | NODE_IF, | 78 | NODE_IF, |
79 | NODE_MATCH, | 79 | NODE_MATCH, |
80 | NODE_CASE, | 80 | NODE_CASE, |
81 | NODE_COND, | ||
82 | NODE_ENUM, | ||
81 | // Helpers. | 83 | // Helpers. |
82 | NODE_SYMBOL_IDX, | 84 | NODE_SYMBOL_IDX, |
83 | NODE_TYPE, | 85 | NODE_TYPE, |
84 | NODE_ARR_TYPE, | 86 | NODE_ARR_TYPE, |
85 | NODE_COMPOUND_TYPE, | 87 | NODE_COMPOUND_TYPE, |
86 | NODE_STRUCT_FIELD, | 88 | NODE_VAL_FIELD, |
87 | NODE_BLOCK, | 89 | NODE_BLOCK, |
88 | } NodeKind; | 90 | } NodeKind; |
89 | 91 | ||
@@ -127,12 +129,14 @@ Str node_str[] = { | |||
127 | [NODE_IF] = cstr("IF"), | 129 | [NODE_IF] = cstr("IF"), |
128 | [NODE_MATCH] = cstr("MATCH"), | 130 | [NODE_MATCH] = cstr("MATCH"), |
129 | [NODE_CASE] = cstr("CASE"), | 131 | [NODE_CASE] = cstr("CASE"), |
132 | [NODE_COND] = cstr("COND"), | ||
133 | [NODE_ENUM] = cstr("ENUM"), | ||
130 | // Helpers. | 134 | // Helpers. |
131 | [NODE_TYPE] = cstr("TYPE"), | 135 | [NODE_TYPE] = cstr("TYPE"), |
132 | [NODE_ARR_TYPE] = cstr("TYPE (ARR)"), | 136 | [NODE_ARR_TYPE] = cstr("TYPE (ARR)"), |
133 | [NODE_SYMBOL_IDX] = cstr("SYMBOL[IDX]"), | 137 | [NODE_SYMBOL_IDX] = cstr("SYMBOL[IDX]"), |
134 | [NODE_COMPOUND_TYPE] = cstr("TYPE (COMPOUND)"), | 138 | [NODE_COMPOUND_TYPE] = cstr("TYPE (COMPOUND)"), |
135 | [NODE_STRUCT_FIELD] = cstr("FIELD"), | 139 | [NODE_VAL_FIELD] = cstr("FIELD"), |
136 | [NODE_BLOCK] = cstr("BLOCK"), | 140 | [NODE_BLOCK] = cstr("BLOCK"), |
137 | }; | 141 | }; |
138 | 142 | ||
@@ -290,8 +294,10 @@ ParseRule parse_rules[] = { | |||
290 | [TOK_LET] = {parse_keyword, NULL, PREC_NONE}, | 294 | [TOK_LET] = {parse_keyword, NULL, PREC_NONE}, |
291 | [TOK_SET] = {parse_keyword, NULL, PREC_NONE}, | 295 | [TOK_SET] = {parse_keyword, NULL, PREC_NONE}, |
292 | [TOK_STRUCT] = {parse_keyword, NULL, PREC_NONE}, | 296 | [TOK_STRUCT] = {parse_keyword, NULL, PREC_NONE}, |
297 | [TOK_ENUM] = {parse_keyword, NULL, PREC_NONE}, | ||
293 | [TOK_IF] = {parse_keyword, NULL, PREC_NONE}, | 298 | [TOK_IF] = {parse_keyword, NULL, PREC_NONE}, |
294 | [TOK_MATCH] = {parse_keyword, NULL, PREC_NONE}, | 299 | [TOK_MATCH] = {parse_keyword, NULL, PREC_NONE}, |
300 | [TOK_COND] = {parse_keyword, NULL, PREC_NONE}, | ||
295 | [TOK_WHILE] = {parse_keyword, NULL, PREC_NONE}, | 301 | [TOK_WHILE] = {parse_keyword, NULL, PREC_NONE}, |
296 | [TOK_CONTINUE] = {parse_keyword, NULL, PREC_NONE}, | 302 | [TOK_CONTINUE] = {parse_keyword, NULL, PREC_NONE}, |
297 | [TOK_BREAK] = {parse_keyword, NULL, PREC_NONE}, | 303 | [TOK_BREAK] = {parse_keyword, NULL, PREC_NONE}, |
@@ -535,14 +541,15 @@ parse_keyword(Parser *parser) { | |||
535 | 541 | ||
536 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | 542 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { |
537 | Node *field = | 543 | Node *field = |
538 | node_alloc(parser, NODE_STRUCT_FIELD, parser->current); | 544 | node_alloc(parser, NODE_VAL_FIELD, parser->current); |
539 | if (!field) return; | 545 | if (!field) return; |
540 | parse_consume( | 546 | parse_consume( |
541 | parser, TOK_SYMBOL, | 547 | parser, TOK_SYMBOL, |
542 | cstr("expected symbol name on struct definition")); | 548 | cstr("expected symbol name on struct definition")); |
543 | parse_symbol(parser); | 549 | parse_symbol(parser); |
544 | field->field_name = array_pop(parser->nodes); | 550 | field->field_name = array_pop(parser->nodes); |
545 | if (field->field_name->next) { | 551 | if (field->field_name->next || |
552 | field->field_name->kind == NODE_SYMBOL_IDX) { | ||
546 | parse_emit_err(parser, prev, | 553 | parse_emit_err(parser, prev, |
547 | cstr("invalid symbol name in struct field")); | 554 | cstr("invalid symbol name in struct field")); |
548 | return; | 555 | return; |
@@ -589,12 +596,12 @@ parse_keyword(Parser *parser) { | |||
589 | // Are we on the default case. | 596 | // Are we on the default case. |
590 | if (!parse_match(parser, TOK_ELSE)) { | 597 | if (!parse_match(parser, TOK_ELSE)) { |
591 | parse_consume(parser, TOK_CASE, | 598 | parse_consume(parser, TOK_CASE, |
592 | cstr("expected case statement")); | 599 | cstr("expected case statement")); |
593 | parse_expr(parser, PREC_LOW); | 600 | parse_expr(parser, PREC_LOW); |
594 | tmp->case_value = array_pop(parser->nodes); | 601 | tmp->case_value = array_pop(parser->nodes); |
595 | } | 602 | } |
596 | parse_consume(parser, TOK_ASSIGN, | 603 | parse_consume(parser, TOK_ASSIGN, |
597 | cstr("malformed case statement")); | 604 | cstr("malformed case statement")); |
598 | parse_expr(parser, PREC_LOW); | 605 | parse_expr(parser, PREC_LOW); |
599 | tmp->case_expr = array_pop(parser->nodes); | 606 | tmp->case_expr = array_pop(parser->nodes); |
600 | array_push(node->match_cases, tmp, parser->storage); | 607 | array_push(node->match_cases, tmp, parser->storage); |
@@ -604,6 +611,36 @@ parse_keyword(Parser *parser) { | |||
604 | // TODO: Check that there are no multiple default or duplicated | 611 | // TODO: Check that there are no multiple default or duplicated |
605 | // cases. | 612 | // cases. |
606 | } break; | 613 | } break; |
614 | case TOK_ENUM: { | ||
615 | node = node_alloc(parser, NODE_ENUM, prev); | ||
616 | if (!node) return; | ||
617 | parse_consume(parser, TOK_SYMBOL, | ||
618 | cstr("expected symbol name on enum definition")); | ||
619 | // Just consume this to avoid conflicts with struct literals. | ||
620 | node->value.sym = parser->previous.val; | ||
621 | parse_consume(parser, TOK_LCURLY, | ||
622 | cstr("expected '{' on enum definition")); | ||
623 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | ||
624 | Node *field = | ||
625 | node_alloc(parser, NODE_VAL_FIELD, parser->current); | ||
626 | if (!field) return; | ||
627 | parse_consume(parser, TOK_SYMBOL, | ||
628 | cstr("expected symbol name on enum definition")); | ||
629 | parse_symbol(parser); | ||
630 | field->field_name = array_pop(parser->nodes); | ||
631 | if (field->field_name->next || | ||
632 | field->field_name->kind == NODE_SYMBOL_IDX) { | ||
633 | parse_emit_err(parser, prev, | ||
634 | cstr("invalid symbol name in enum field")); | ||
635 | return; | ||
636 | } | ||
637 | if (parse_match(parser, TOK_ASSIGN)) { | ||
638 | parse_expr(parser, PREC_LOW); | ||
639 | field->field_val = array_pop(parser->nodes); | ||
640 | } | ||
641 | array_push(node->struct_field, field, parser->storage); | ||
642 | } | ||
643 | } break; | ||
607 | default: return; // Unreachable. | 644 | default: return; // Unreachable. |
608 | } | 645 | } |
609 | array_push(parser->nodes, node, parser->storage); | 646 | array_push(parser->nodes, node, parser->storage); |
@@ -741,8 +778,7 @@ parse_symbol(Parser *parser) { | |||
741 | // Struct literal. | 778 | // Struct literal. |
742 | node->kind = NODE_STRUCT_LIT; | 779 | node->kind = NODE_STRUCT_LIT; |
743 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | 780 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { |
744 | Node *field = | 781 | Node *field = node_alloc(parser, NODE_VAL_FIELD, parser->current); |
745 | node_alloc(parser, NODE_STRUCT_FIELD, parser->current); | ||
746 | parse_consume(parser, TOK_SYMBOL, cstr("expected symbol name")); | 782 | parse_consume(parser, TOK_SYMBOL, cstr("expected symbol name")); |
747 | parse_symbol(parser); | 783 | parse_symbol(parser); |
748 | field->field_name = array_pop(parser->nodes); | 784 | field->field_name = array_pop(parser->nodes); |
@@ -831,6 +867,7 @@ graph_node(Node *node) { | |||
831 | graph_node(next); | 867 | graph_node(next); |
832 | } | 868 | } |
833 | } break; | 869 | } break; |
870 | case NODE_ENUM: | ||
834 | case NODE_STRUCT: { | 871 | case NODE_STRUCT: { |
835 | for (sz i = 0; i < array_size(node->struct_field); i++) { | 872 | for (sz i = 0; i < array_size(node->struct_field); i++) { |
836 | Node *next = node->struct_field[i]; | 873 | Node *next = node->struct_field[i]; |
@@ -852,7 +889,7 @@ graph_node(Node *node) { | |||
852 | graph_node(node->cond_else); | 889 | graph_node(node->cond_else); |
853 | } | 890 | } |
854 | } break; | 891 | } break; |
855 | case NODE_STRUCT_FIELD: | 892 | case NODE_VAL_FIELD: |
856 | case NODE_SET: | 893 | case NODE_SET: |
857 | case NODE_LET: { | 894 | case NODE_LET: { |
858 | if (node->var_name) { | 895 | if (node->var_name) { |