From 96148f86a791cb25d0112cd8551db410b1352e8b Mon Sep 17 00:00:00 2001 From: paulboul1013 Date: Sun, 29 Mar 2026 13:13:57 +0800 Subject: [PATCH] feat: support local union struct and enum declarations --- src/parser/parser_stmt.c | 13 ++++++++++++ src/parser/parser_struct.c | 4 ++++ tests/compiler/codegen/emit_source_mapping.zc | 21 +++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/parser/parser_stmt.c b/src/parser/parser_stmt.c index 86d78d8c..1f44e5f1 100644 --- a/src/parser/parser_stmt.c +++ b/src/parser/parser_stmt.c @@ -2587,6 +2587,19 @@ ASTNode *parse_statement(ParserContext *ctx, Lexer *l) { return parse_impl(ctx, l); } + if (tk.type == TOK_IDENT && strncmp(tk.start, "struct", 6) == 0 && tk.len == 6) + { + return parse_struct(ctx, l, 0, 0); + } + if (tk.type == TOK_UNION) + { + return parse_struct(ctx, l, 1, 0); + } + if (tk.type == TOK_IDENT && strncmp(tk.start, "enum", 4) == 0 && tk.len == 4) + { + return parse_enum(ctx, l); + } + if (tk.type == TOK_AUTOFREE) { lexer_next(l); diff --git a/src/parser/parser_struct.c b/src/parser/parser_struct.c index c6551203..71f1495e 100644 --- a/src/parser/parser_struct.c +++ b/src/parser/parser_struct.c @@ -864,6 +864,7 @@ ASTNode *parse_struct(ParserContext *ctx, Lexer *l, int is_union, int is_opaque) { lexer_next(l); ASTNode *node = ast_create(NODE_STRUCT); + node->token = name_token; node->strct.name = name; node->strct.is_template = (gp_count > 0); node->strct.generic_params = gps; @@ -1053,6 +1054,7 @@ ASTNode *parse_struct(ParserContext *ctx, Lexer *l, int is_union, int is_opaque) } ASTNode *node = ast_create(NODE_STRUCT); + node->token = name_token; add_to_struct_list(ctx, node); node->strct.name = name; @@ -1120,6 +1122,7 @@ ASTNode *parse_enum(ParserContext *ctx, Lexer *l) lexer_next(l); Token n = lexer_next(l); check_identifier(ctx, n); + Token name_token = n; char *gp = NULL; if (lexer_peek(l).type == TOK_LANGLE) @@ -1277,6 +1280,7 @@ ASTNode *parse_enum(ParserContext *ctx, Lexer *l) } ASTNode *node = ast_create(NODE_ENUM); + node->token = name_token; node->enm.name = ename; node->enm.variants = h; diff --git a/tests/compiler/codegen/emit_source_mapping.zc b/tests/compiler/codegen/emit_source_mapping.zc index 6466253d..62a5ff44 100644 --- a/tests/compiler/codegen/emit_source_mapping.zc +++ b/tests/compiler/codegen/emit_source_mapping.zc @@ -43,11 +43,32 @@ fn main() { let log = Log {}; log.verbose("Hello, mars!"); + struct LocalPoint { + x: int; + y: int; + } + + enum LocalState { + Ready, + Busy, + } + + union LocalValue { + i: int; + } + + let local_point = LocalPoint { x: 3, y: 4 }; + let local_state = LocalState::Ready; + let local_value = LocalValue { i: 8 }; + let point = Point { x: (f64)my_function(), y: 512.0, }; point.mark_unused(); + assert(local_point.x == 3, "local struct failed"); + assert(local_state == LocalState::Ready, "local enum failed"); + assert(local_value.i == 8, "local union failed"); for(let i = 0; i < 10; ++i) {