aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c55
1 files changed, 46 insertions, 9 deletions
diff --git a/src/main.c b/src/main.c
index ccd4877..f73c7cc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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) {