From 1ceda902076933a8d75873518cc7cf6fb2ac2af6 Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Sun, 12 Jul 2026 14:20:41 +0800 Subject: [PATCH] =?UTF-8?q?stage1=20=E4=BF=AE=E5=A4=8D=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E8=A7=A3=E6=9E=90=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=B5=8C=E5=A5=97=E7=BB=93=E6=9E=84=E4=BD=93=E5=AD=97=E9=9D=A2?= =?UTF-8?q?=E9=87=8F=E6=97=A0=E9=99=90=E5=BE=AA=E7=8E=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stage1/spl_expr.c | 14 ++++++++++++-- stage1/spl_parser.c | 41 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/stage1/spl_expr.c b/stage1/spl_expr.c index eba9f0f..e95eb9c 100644 --- a/stage1/spl_expr.c +++ b/stage1/spl_expr.c @@ -467,7 +467,12 @@ static void parse_one_field_init(spl_comp_t *ctx, spl_field_vec_t *fields, int b spl_emit(ctx, SPL_DROP, SPL_VOID, 0); } else if (f->type && (f->type->kind == TYPE_STRUCT || f->type->kind == TYPE_ENUM) && spl_type_size(f->type) > sizeof(spl_val_t)) { - spl_expr_result_t fv = spl_parse_expr(ctx, PREC_MIN); + spl_expr_result_t fv; + if (peek(ctx)->type == TOK_L_BRACE) { + fv = spl_parse_struct_literal(ctx, f->type); + } else { + fv = spl_parse_expr(ctx, PREC_MIN); + } (void)fv; usize nslots = (spl_type_size(f->type) + sizeof(spl_val_t) - 1) / sizeof(spl_val_t); spl_emit_copy_slots(ctx, base_offset + (int)extra_offset + f->offset, nslots); @@ -583,7 +588,12 @@ spl_expr_result_t spl_parse_struct_literal(spl_comp_t *ctx, spl_type_info_t *typ (v->data_type->kind == TYPE_STRUCT || v->data_type->kind == TYPE_ENUM) && spl_type_size(v->data_type) > sizeof(spl_val_t)) { - spl_expr_result_t dv = spl_parse_expr(ctx, PREC_MIN); + spl_expr_result_t dv; + if (peek(ctx)->type == TOK_L_BRACE) { + dv = spl_parse_struct_literal(ctx, v->data_type); + } else { + dv = spl_parse_expr(ctx, PREC_MIN); + } (void)dv; usize nslots = (spl_type_size(v->data_type) + sizeof(spl_val_t) - 1) / sizeof(spl_val_t); diff --git a/stage1/spl_parser.c b/stage1/spl_parser.c index c0c2700..c18f85c 100644 --- a/stage1/spl_parser.c +++ b/stage1/spl_parser.c @@ -107,7 +107,6 @@ static void parse_fn_decl(spl_comp_t *ctx, int is_extern, int is_pub) { spl_tok_t *fname_tok = advance(ctx); char fn_name[256]; spl_tok_copy_name(fname_tok, fn_name, sizeof(fn_name)); - skip_nl(ctx); expect(ctx, TOK_L_PAREN); @@ -159,7 +158,6 @@ static void parse_method_decl(spl_comp_t *ctx, spl_type_info_t *container) { spl_tok_t *mname_tok = advance(ctx); char mname[256]; spl_tok_copy_name(mname_tok, mname, sizeof(mname)); - /* Build qualified name: TypeName.method_name */ char qualified[512]; snprintf(qualified, sizeof(qualified), "%s.%s", container->name ? container->name : "anon", @@ -219,6 +217,40 @@ static void parse_method_decl(spl_comp_t *ctx, spl_type_info_t *container) { * fn name(...) type { } — methods * ============================================================ */ +/* Skip past a nested type declaration in pass 2 without re-parsing */ +static void skip_type_decl(spl_comp_t *ctx) { + advance(ctx); /* type */ + advance(ctx); /* name */ + skip_nl(ctx); + expect(ctx, TOK_ASSIGN); + skip_nl(ctx); + + spl_tok_type_t tt = peek(ctx)->type; + if (tt == KW_STRUCT || tt == KW_UNION || tt == KW_ENUM) { + advance(ctx); + skip_nl(ctx); + } + + if (peek(ctx)->type == TOK_L_BRACE) { + int bd = 1; + advance(ctx); + while (bd > 0 && ctx->tok_idx < vec_size(ctx->toks)) { + if (peek(ctx)->type == TOK_L_BRACE) + bd++; + else if (peek(ctx)->type == TOK_R_BRACE) + bd--; + advance(ctx); + } + } else { + while (peek(ctx)->type != TOK_SEMICOLON && peek(ctx)->type != TOK_EOF) + advance(ctx); + } + + skip_nl(ctx); + if (peek(ctx)->type == TOK_SEMICOLON) + advance(ctx); +} + static void parse_type_body(spl_comp_t *ctx, spl_type_info_t *container, int is_enum) { if (peek(ctx)->type != TOK_L_BRACE) return; @@ -265,8 +297,7 @@ static void parse_type_body(spl_comp_t *ctx, spl_type_info_t *container, int is_ } advance(ctx); } else if (tt == KW_TYPE && depth == 1) { - /* Nested type — already parsed in pass 1, skip */ - parse_type_decl(ctx); + skip_type_decl(ctx); } else if (tt == KW_VAR && depth == 1 && !is_enum) { /* var name: type; (struct/union only) */ advance(ctx); /* var */ @@ -426,7 +457,7 @@ void spl_parse_prog(spl_comp_t *ctx) { parse_fn_decl(ctx, 1, 0); break; default: { - int prev = ctx->tok_idx; + int prev = ctx->tok_idx; /* Safety: prevent infinite loop */ /* Try to parse as a statement */ spl_parse_stmt(ctx); /* Safety: prevent infinite loop on unrecognized tokens */