aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-18 14:15:37 +0200
committerBad Diode <bd@badd10de.dev>2024-06-18 14:15:37 +0200
commit37f703d1252d39047ab71ef15c62855e44de897b (patch)
treecb049bf7a30e0a6c4dec0c5cca2707e08fcc9013
parentd56cbdb065fa12d9e2bec375f65ef67d611c61bb (diff)
downloadbdl-37f703d1252d39047ab71ef15c62855e44de897b.tar.gz
bdl-37f703d1252d39047ab71ef15c62855e44de897b.zip
Add pointers
-rw-r--r--src/main.c54
-rw-r--r--tests/variables.bad8
2 files changed, 43 insertions, 19 deletions
diff --git a/src/main.c b/src/main.c
index 57d09bd..3454587 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
223ParseRule parse_rules[] = { 224ParseRule 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("\"];");
diff --git a/tests/variables.bad b/tests/variables.bad
index 473bb3c..990685f 100644
--- a/tests/variables.bad
+++ b/tests/variables.bad
@@ -58,3 +58,11 @@ let particle = entity {
58let numbers: u32[0xff] 58let numbers: u32[0xff]
59set numbers[0] = 32 59set numbers[0] = 32
60set numbers[1] = 42 60set numbers[1] = 42
61
62; Arrays are syntactic sugar for pointers (@).
63let ptr:@u32 = numbers
64set ptr[10] = 33
65
66; Strings hold a .mem and .size fields with the number of bytes it holds.
67let hello: str = "hello world"
68set c[1] = 'a' ; "hallo world"