diff options
| author | Mel <mel@rnrd.eu> | 2025-06-14 00:14:58 +0200 |
|---|---|---|
| committer | Mel <mel@rnrd.eu> | 2025-06-14 00:14:58 +0200 |
| commit | 4a49045f77b5be5d82e84c6e3e57721686ec5a0a (patch) | |
| tree | 3143861a9a6d66e6acbe8c7273aaa0bbc0e486bc /boot/parse.c | |
| parent | 3e7acb02962b05db8cf83e5b6b082ac368c8c88e (diff) | |
| download | catskill-4a49045f77b5be5d82e84c6e3e57721686ec5a0a.tar.zst catskill-4a49045f77b5be5d82e84c6e3e57721686ec5a0a.zip | |
Disambiguate variable declaration and call/array access syntax with `var` + `let`
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'boot/parse.c')
| -rw-r--r-- | boot/parse.c | 41 |
1 files changed, 16 insertions, 25 deletions
diff --git a/boot/parse.c b/boot/parse.c index a0dd12c..6129950 100644 --- a/boot/parse.c +++ b/boot/parse.c @@ -193,26 +193,6 @@ parser_end_statement(struct Parser* p, struct Parser_Error* error) parser_next(p); } -// checks if the next 2 tokens could begin a variable declaration. -bool -parser_could_be_variable_declaration(struct Parser* p) -{ - // NOTE: these can be a variable declaration: - // x uint = 123 - // me, them Obj = create() - // otherwise without a type, it is instead counted as an assignment: - // a = "hi!" - - // NOTE: maybe move this into `lex.c`? - // or change the API a bit, this isn't really a parser method. - struct Token first = parser_peek(p); - struct Token second = parser_peek_further(p); - - bool first_matches = token_is(&first, TOKEN_NAME); - bool second_matches = token_is(&second, TOKEN_COMMA) || token_can_begin_type(&second); - return first_matches && second_matches; -} - struct Block_Node parser_block_node(struct Parser* p, struct Parser_Error* error) { @@ -795,6 +775,12 @@ parser_expression(struct Parser* p, struct Parser_Error* error) struct Statement* parser_statement_declaration(struct Parser* p, struct Parser_Error* error) { + struct Token declaration_token = parser_next(p); + + enum Statement_Declaration_Kind declaration_kind = + statement_declaration_kind_from_token(&declaration_token); + check(declaration_kind, "expected valid declaration token"); + struct String_Array names = string_array_new(); struct Span span = { 0 }; @@ -819,6 +805,7 @@ parser_statement_declaration(struct Parser* p, struct Parser_Error* error) span = span_merge(span, initializer->span); union Statement_Value value = { .declaration = { + .kind = declaration_kind, .names = names, .type = type, .initializer = initializer, @@ -882,16 +869,20 @@ parser_statement_loop(struct Parser* p, struct Parser_Error* error) struct Token for_token = CHECK(parser_need(p, TOKEN_WORD_FOR, error)); // these are the possible for loop variants: - // * `for String name = collection {}`, as iteration over container + // * `for var name String = collection {}`, as iteration over container // * `for check() {}`, as a simple while-style loop - // * `for u8 i = 0, i < 10, i++ {}`, as a c-style semi-semi loop + // * `for var i u8 = 0, i < 10, i++ {}`, as a c-style semi-semi loop // * `for {}`, as an infinite loop struct Statement* declaration = nil; struct Expression *condition = nil, *iteration = nil; // c-style or iterator-style - if (parser_could_be_variable_declaration(p)) { + struct Token next = parser_peek(p); + // TODO: i do not like the `for var` combination, it is too verbose. + // it would be beneficial to bring back `while`, so that declarations without `var` + // are no longer ambiguous. + if (token_can_begin_declaration(&next)) { declaration = CHECK(parser_statement_declaration(p, error)); // c-style @@ -905,7 +896,7 @@ parser_statement_loop(struct Parser* p, struct Parser_Error* error) } // while-style - if (!parser_probe(p, TOKEN_CURLY_OPEN)) condition = CHECK(parser_expression(p, error)); + if (!token_is(&next, TOKEN_CURLY_OPEN)) condition = CHECK(parser_expression(p, error)); struct Block_Node body = CHECK(parser_block_node(p, error)); struct Span span = span_merge(for_token.span, body.span); @@ -1007,7 +998,7 @@ parser_statement(struct Parser* p, struct Parser_Error* error) token = parser_peek(p); } - if (parser_could_be_variable_declaration(p)) return parser_statement_declaration(p, error); + if (token_can_begin_declaration(&token)) return parser_statement_declaration(p, error); switch (token.kind) { case TOKEN_WORD_IF: |
