From 4ec376b67d605910cb7757dc2e15a28a942f59ca Mon Sep 17 00:00:00 2001 From: Mel Date: Thu, 28 May 2026 04:24:51 +0200 Subject: Correct type modifier combinations and grouping Signed-off-by: Mel --- boot/parse.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'boot/parse.c') diff --git a/boot/parse.c b/boot/parse.c index 56d767a..ef71540 100644 --- a/boot/parse.c +++ b/boot/parse.c @@ -381,6 +381,8 @@ parser_block_node(struct Parser* p, struct Parser_Error* error) if (!parser_probe(p, TOKEN_CURLY_CLOSE)) CHECK_RETURN(parser_end_statement(p, error), struct Tree_Block); + parser_unglue(p); + if (!head) { head = statement; } else { @@ -401,6 +403,7 @@ parser_block_node(struct Parser* p, struct Parser_Error* error) } struct Tree_Type* parser_node_type(struct Parser* p, struct Parser_Error* error); +struct Tree_Type* parser_node_type_inner(struct Parser* p, struct Parser_Error* error); struct Tree_Function_Header parser_function_header_node(struct Parser* p, struct Parser_Error* error) @@ -710,6 +713,11 @@ parser_node_type_tuple(struct Parser* p, struct Parser_Error* error) } struct Token close_token = CHECK(parser_need(p, TOKEN_ROUND_CLOSE, error)); + + // single-element tuples are equivalent to their inner type, + // which allows us to use them for grouping. + if (head && !head->next) return head; + struct Span span = span_merge(open_token.span, close_token.span); return tree_type_new( TREE_TYPE_TUPLE, (union Tree_Type_Value){ .tuple = { head } }, span, open_token.location); @@ -759,18 +767,31 @@ parser_node_type_array_or_map(struct Parser* p, struct Parser_Error* error) struct Tree_Type* parser_node_type_reference(struct Parser* p, struct Parser_Error* error) { - struct Token ampersand_token = CHECK(parser_need(p, TOKEN_AMPERSAND, error)); + // we accept a fused `&&` token as two references + struct Token sigil = parser_next(p); + bool double_ref = token_is(&sigil, TOKEN_AND); + if (!double_ref && !token_is(&sigil, TOKEN_AMPERSAND)) { + parser_error(error, PARSER_ERROR_UNEXPECTED_TOKEN, sigil); + return nil; + } - struct Tree_Type* referenced_type = CHECK(parser_node_type(p, error)); + struct Tree_Type* referenced_type = CHECK(parser_node_type_inner(p, error)); if (!referenced_type) { - parser_error(error, PARSER_ERROR_EXPECTED_TYPE, ampersand_token); + parser_error(error, PARSER_ERROR_EXPECTED_TYPE, sigil); return nil; } - struct Span span = span_merge(ampersand_token.span, referenced_type->span); - return tree_type_new( + struct Span span = span_merge(sigil.span, referenced_type->span); + struct Tree_Type* ref = tree_type_new( TREE_TYPE_REFERENCE, (union Tree_Type_Value){ .reference = { referenced_type } }, span, - ampersand_token.location); + sigil.location); + + if (double_ref) { + ref = tree_type_new( + TREE_TYPE_REFERENCE, (union Tree_Type_Value){ .reference = { ref } }, span, + sigil.location); + } + return ref; } struct Tree_Type* @@ -793,6 +814,7 @@ parser_node_type_inner(struct Parser* p, struct Parser_Error* error) case TOKEN_SQUARE_OPEN: return parser_node_type_array_or_map(p, error); case TOKEN_AMPERSAND: + case TOKEN_AND: return parser_node_type_reference(p, error); default: parser_error(error, PARSER_ERROR_UNEXPECTED_TOKEN, token); -- cgit 1.4.1