From 37f703d1252d39047ab71ef15c62855e44de897b Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 18 Jun 2024 14:15:37 +0200 Subject: Add pointers --- src/main.c | 54 ++++++++++++++++++++++++++++++++++------------------- tests/variables.bad | 8 ++++++++ 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 { NODE_SET, NODE_STRUCT, // Helpers. - NODE_SYMBOL_ARR, + NODE_SYMBOL_IDX, NODE_TYPE, NODE_ARR_TYPE, NODE_COMPOUND_TYPE, @@ -123,7 +123,7 @@ Str node_str[] = { // Helpers. [NODE_TYPE] = cstr("TYPE"), [NODE_ARR_TYPE] = cstr("TYPE (ARR)"), - [NODE_SYMBOL_ARR] = cstr("SYMBOL (ARR)"), + [NODE_SYMBOL_IDX] = cstr("SYMBOL[IDX]"), [NODE_COMPOUND_TYPE] = cstr("TYPE (COMPOUND)"), [NODE_STRUCT_FIELD] = cstr("FIELD"), }; @@ -161,6 +161,7 @@ typedef struct Node { struct Node **struct_field; struct Node **elements; }; + bool is_ptr; } Node; // @@ -223,6 +224,7 @@ void parse_type(Parser *parser); ParseRule parse_rules[] = { [TOK_LPAREN] = {parse_grouping, NULL, PREC_NONE}, [TOK_LCURLY] = {NULL, NULL, PREC_NONE}, + [TOK_AT] = {parse_symbol, NULL, PREC_NONE}, // Arithmetic. [TOK_SUB] = {parse_unary, parse_binary, PREC_TERM}, @@ -401,6 +403,9 @@ parse_type(Parser *parser) { #endif Node *node = node_alloc(parser, NODE_TYPE, prev); if (!node) return; + if (parse_match(parser, TOK_AT)) { + node->is_ptr = true; + } if (parse_match(parser, TOK_LCURLY)) { node->kind = NODE_COMPOUND_TYPE; while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { @@ -419,8 +424,7 @@ parse_type(Parser *parser) { // Optional array value? if (parse_match(parser, TOK_LSQUARE)) { node->kind = NODE_ARR_TYPE, - parse_consume(parser, TOK_NUM_INT, - cstr("no array size given")); + parse_consume(parser, TOK_NUM_INT, cstr("no array size given")); parse_number(parser); node->arr_size = array_pop(parser->nodes); parse_consume(parser, TOK_RSQUARE, @@ -626,20 +630,28 @@ parse_symbol(Parser *parser) { print("parsing symbol "); print_token(prev); #endif - Node *node; + if (prev.kind == TOK_AT) { + parse_consume(parser, TOK_SYMBOL, + cstr("expected symbol after '.' operator")); + parse_symbol(parser); + Node *node = array_pop(parser->nodes); + if (node) { + node->is_ptr = true; + array_push(parser->nodes, node, parser->storage); + } + return; + } + Node *node = node_alloc(parser, NODE_SYMBOL, prev); + if (!node) return; if (parse_match(parser, TOK_DOT)) { // Symbol chain. parse_consume(parser, TOK_SYMBOL, cstr("expected symbol after '.' operator")); - node = node_alloc(parser, NODE_SYMBOL, prev); - if (!node) return; parse_symbol(parser); node->next = array_pop(parser->nodes); } else if (parse_match(parser, TOK_LCURLY)) { // Struct literal. - node = node_alloc(parser, NODE_STRUCT_LIT, prev); - if (!node) return; - + node->kind = NODE_STRUCT_LIT; while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { Node *field = node_alloc(parser, NODE_STRUCT_FIELD, parser->current); @@ -652,14 +664,12 @@ parse_symbol(Parser *parser) { array_push(node->elements, field, parser->storage); } } else if (parse_match(parser, TOK_LSQUARE)) { - node = node_alloc(parser, NODE_SYMBOL_ARR, prev); - if (!node) return; - parse_consume(parser, TOK_NUM_INT, - cstr("no array size given")); + node->kind = NODE_SYMBOL_IDX; + parse_consume(parser, TOK_NUM_INT, cstr("no array size given")); parse_number(parser); node->arr_size = array_pop(parser->nodes); parse_consume(parser, TOK_RSQUARE, - cstr("unmatched brackets ']' in array type")); + cstr("unmatched brackets ']' in array type")); } else { node = node_alloc(parser, NODE_SYMBOL, prev); if (!node) return; @@ -690,11 +700,17 @@ graph_node(Node *node) { case NODE_NUM_UINT: print("| Value: %x", node->value.u); break; case NODE_NUM_FLOAT: print("| Value: %f{2}", node->value.d); break; case NODE_STRING: print("| Value: %s", node->value.str); break; - case NODE_SYMBOL_ARR: print("| Name: %s", node->value.sym); break; - case NODE_SYMBOL: print("| Name: %s", node->value.sym); break; - case NODE_STRUCT: print("| Name: %s", node->value.sym); break; + case NODE_SYMBOL_IDX: + case NODE_STRUCT: case NODE_STRUCT_LIT: print("| Name: %s", node->value.sym); break; - case NODE_TYPE: print("| Name: %s", node->value.sym); break; + case NODE_SYMBOL: + case NODE_TYPE: { + if (node->is_ptr) { + print("| Name: @%s", node->value.sym); + } else { + print("| Name: %s", node->value.sym); + } + } break; default: break; } 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 { let numbers: u32[0xff] set numbers[0] = 32 set numbers[1] = 42 + +; Arrays are syntactic sugar for pointers (@). +let ptr:@u32 = numbers +set ptr[10] = 33 + +; Strings hold a .mem and .size fields with the number of bytes it holds. +let hello: str = "hello world" +set c[1] = 'a' ; "hallo world" -- cgit v1.2.1