diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 54 |
1 files changed, 35 insertions, 19 deletions
@@ -76,7 +76,7 @@ typedef enum NodeKind { | |||
76 | NODE_SET, | 76 | NODE_SET, |
77 | NODE_STRUCT, | 77 | NODE_STRUCT, |
78 | // Helpers. | 78 | // Helpers. |
79 | NODE_SYMBOL_ARR, | 79 | NODE_SYMBOL_IDX, |
80 | NODE_TYPE, | 80 | NODE_TYPE, |
81 | NODE_ARR_TYPE, | 81 | NODE_ARR_TYPE, |
82 | NODE_COMPOUND_TYPE, | 82 | NODE_COMPOUND_TYPE, |
@@ -123,7 +123,7 @@ Str node_str[] = { | |||
123 | // Helpers. | 123 | // Helpers. |
124 | [NODE_TYPE] = cstr("TYPE"), | 124 | [NODE_TYPE] = cstr("TYPE"), |
125 | [NODE_ARR_TYPE] = cstr("TYPE (ARR)"), | 125 | [NODE_ARR_TYPE] = cstr("TYPE (ARR)"), |
126 | [NODE_SYMBOL_ARR] = cstr("SYMBOL (ARR)"), | 126 | [NODE_SYMBOL_IDX] = cstr("SYMBOL[IDX]"), |
127 | [NODE_COMPOUND_TYPE] = cstr("TYPE (COMPOUND)"), | 127 | [NODE_COMPOUND_TYPE] = cstr("TYPE (COMPOUND)"), |
128 | [NODE_STRUCT_FIELD] = cstr("FIELD"), | 128 | [NODE_STRUCT_FIELD] = cstr("FIELD"), |
129 | }; | 129 | }; |
@@ -161,6 +161,7 @@ typedef struct Node { | |||
161 | struct Node **struct_field; | 161 | struct Node **struct_field; |
162 | struct Node **elements; | 162 | struct Node **elements; |
163 | }; | 163 | }; |
164 | bool is_ptr; | ||
164 | } Node; | 165 | } Node; |
165 | 166 | ||
166 | // | 167 | // |
@@ -223,6 +224,7 @@ void parse_type(Parser *parser); | |||
223 | ParseRule parse_rules[] = { | 224 | ParseRule parse_rules[] = { |
224 | [TOK_LPAREN] = {parse_grouping, NULL, PREC_NONE}, | 225 | [TOK_LPAREN] = {parse_grouping, NULL, PREC_NONE}, |
225 | [TOK_LCURLY] = {NULL, NULL, PREC_NONE}, | 226 | [TOK_LCURLY] = {NULL, NULL, PREC_NONE}, |
227 | [TOK_AT] = {parse_symbol, NULL, PREC_NONE}, | ||
226 | 228 | ||
227 | // Arithmetic. | 229 | // Arithmetic. |
228 | [TOK_SUB] = {parse_unary, parse_binary, PREC_TERM}, | 230 | [TOK_SUB] = {parse_unary, parse_binary, PREC_TERM}, |
@@ -401,6 +403,9 @@ parse_type(Parser *parser) { | |||
401 | #endif | 403 | #endif |
402 | Node *node = node_alloc(parser, NODE_TYPE, prev); | 404 | Node *node = node_alloc(parser, NODE_TYPE, prev); |
403 | if (!node) return; | 405 | if (!node) return; |
406 | if (parse_match(parser, TOK_AT)) { | ||
407 | node->is_ptr = true; | ||
408 | } | ||
404 | if (parse_match(parser, TOK_LCURLY)) { | 409 | if (parse_match(parser, TOK_LCURLY)) { |
405 | node->kind = NODE_COMPOUND_TYPE; | 410 | node->kind = NODE_COMPOUND_TYPE; |
406 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | 411 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { |
@@ -419,8 +424,7 @@ parse_type(Parser *parser) { | |||
419 | // Optional array value? | 424 | // Optional array value? |
420 | if (parse_match(parser, TOK_LSQUARE)) { | 425 | if (parse_match(parser, TOK_LSQUARE)) { |
421 | node->kind = NODE_ARR_TYPE, | 426 | node->kind = NODE_ARR_TYPE, |
422 | parse_consume(parser, TOK_NUM_INT, | 427 | parse_consume(parser, TOK_NUM_INT, cstr("no array size given")); |
423 | cstr("no array size given")); | ||
424 | parse_number(parser); | 428 | parse_number(parser); |
425 | node->arr_size = array_pop(parser->nodes); | 429 | node->arr_size = array_pop(parser->nodes); |
426 | parse_consume(parser, TOK_RSQUARE, | 430 | parse_consume(parser, TOK_RSQUARE, |
@@ -626,20 +630,28 @@ parse_symbol(Parser *parser) { | |||
626 | print("parsing symbol "); | 630 | print("parsing symbol "); |
627 | print_token(prev); | 631 | print_token(prev); |
628 | #endif | 632 | #endif |
629 | Node *node; | 633 | if (prev.kind == TOK_AT) { |
634 | parse_consume(parser, TOK_SYMBOL, | ||
635 | cstr("expected symbol after '.' operator")); | ||
636 | parse_symbol(parser); | ||
637 | Node *node = array_pop(parser->nodes); | ||
638 | if (node) { | ||
639 | node->is_ptr = true; | ||
640 | array_push(parser->nodes, node, parser->storage); | ||
641 | } | ||
642 | return; | ||
643 | } | ||
644 | Node *node = node_alloc(parser, NODE_SYMBOL, prev); | ||
645 | if (!node) return; | ||
630 | if (parse_match(parser, TOK_DOT)) { | 646 | if (parse_match(parser, TOK_DOT)) { |
631 | // Symbol chain. | 647 | // Symbol chain. |
632 | parse_consume(parser, TOK_SYMBOL, | 648 | parse_consume(parser, TOK_SYMBOL, |
633 | cstr("expected symbol after '.' operator")); | 649 | cstr("expected symbol after '.' operator")); |
634 | node = node_alloc(parser, NODE_SYMBOL, prev); | ||
635 | if (!node) return; | ||
636 | parse_symbol(parser); | 650 | parse_symbol(parser); |
637 | node->next = array_pop(parser->nodes); | 651 | node->next = array_pop(parser->nodes); |
638 | } else if (parse_match(parser, TOK_LCURLY)) { | 652 | } else if (parse_match(parser, TOK_LCURLY)) { |
639 | // Struct literal. | 653 | // Struct literal. |
640 | node = node_alloc(parser, NODE_STRUCT_LIT, prev); | 654 | node->kind = NODE_STRUCT_LIT; |
641 | if (!node) return; | ||
642 | |||
643 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | 655 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { |
644 | Node *field = | 656 | Node *field = |
645 | node_alloc(parser, NODE_STRUCT_FIELD, parser->current); | 657 | node_alloc(parser, NODE_STRUCT_FIELD, parser->current); |
@@ -652,14 +664,12 @@ parse_symbol(Parser *parser) { | |||
652 | array_push(node->elements, field, parser->storage); | 664 | array_push(node->elements, field, parser->storage); |
653 | } | 665 | } |
654 | } else if (parse_match(parser, TOK_LSQUARE)) { | 666 | } else if (parse_match(parser, TOK_LSQUARE)) { |
655 | node = node_alloc(parser, NODE_SYMBOL_ARR, prev); | 667 | node->kind = NODE_SYMBOL_IDX; |
656 | if (!node) return; | 668 | parse_consume(parser, TOK_NUM_INT, cstr("no array size given")); |
657 | parse_consume(parser, TOK_NUM_INT, | ||
658 | cstr("no array size given")); | ||
659 | parse_number(parser); | 669 | parse_number(parser); |
660 | node->arr_size = array_pop(parser->nodes); | 670 | node->arr_size = array_pop(parser->nodes); |
661 | parse_consume(parser, TOK_RSQUARE, | 671 | parse_consume(parser, TOK_RSQUARE, |
662 | cstr("unmatched brackets ']' in array type")); | 672 | cstr("unmatched brackets ']' in array type")); |
663 | } else { | 673 | } else { |
664 | node = node_alloc(parser, NODE_SYMBOL, prev); | 674 | node = node_alloc(parser, NODE_SYMBOL, prev); |
665 | if (!node) return; | 675 | if (!node) return; |
@@ -690,11 +700,17 @@ graph_node(Node *node) { | |||
690 | case NODE_NUM_UINT: print("| Value: %x", node->value.u); break; | 700 | case NODE_NUM_UINT: print("| Value: %x", node->value.u); break; |
691 | case NODE_NUM_FLOAT: print("| Value: %f{2}", node->value.d); break; | 701 | case NODE_NUM_FLOAT: print("| Value: %f{2}", node->value.d); break; |
692 | case NODE_STRING: print("| Value: %s", node->value.str); break; | 702 | case NODE_STRING: print("| Value: %s", node->value.str); break; |
693 | case NODE_SYMBOL_ARR: print("| Name: %s", node->value.sym); break; | 703 | case NODE_SYMBOL_IDX: |
694 | case NODE_SYMBOL: print("| Name: %s", node->value.sym); break; | 704 | case NODE_STRUCT: |
695 | case NODE_STRUCT: print("| Name: %s", node->value.sym); break; | ||
696 | case NODE_STRUCT_LIT: print("| Name: %s", node->value.sym); break; | 705 | case NODE_STRUCT_LIT: print("| Name: %s", node->value.sym); break; |
697 | case NODE_TYPE: print("| Name: %s", node->value.sym); break; | 706 | case NODE_SYMBOL: |
707 | case NODE_TYPE: { | ||
708 | if (node->is_ptr) { | ||
709 | print("| Name: @%s", node->value.sym); | ||
710 | } else { | ||
711 | print("| Name: %s", node->value.sym); | ||
712 | } | ||
713 | } break; | ||
698 | default: break; | 714 | default: break; |
699 | } | 715 | } |
700 | println("\"];"); | 716 | println("\"];"); |