stage1 修复类型重复解析 修复嵌套结构体字面量无限循环

This commit is contained in:
zzy
2026-07-12 14:20:41 +08:00
parent 9b9b25ce0f
commit 1ceda90207
2 changed files with 48 additions and 7 deletions

View File

@@ -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 */