stage1 修复类型重复解析 修复嵌套结构体字面量无限循环
This commit is contained in:
@@ -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);
|
spl_emit(ctx, SPL_DROP, SPL_VOID, 0);
|
||||||
} else if (f->type && (f->type->kind == TYPE_STRUCT || f->type->kind == TYPE_ENUM) &&
|
} else if (f->type && (f->type->kind == TYPE_STRUCT || f->type->kind == TYPE_ENUM) &&
|
||||||
spl_type_size(f->type) > sizeof(spl_val_t)) {
|
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;
|
(void)fv;
|
||||||
usize nslots = (spl_type_size(f->type) + sizeof(spl_val_t) - 1) / sizeof(spl_val_t);
|
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);
|
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_STRUCT ||
|
||||||
v->data_type->kind == TYPE_ENUM) &&
|
v->data_type->kind == TYPE_ENUM) &&
|
||||||
spl_type_size(v->data_type) > sizeof(spl_val_t)) {
|
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;
|
(void)dv;
|
||||||
usize nslots = (spl_type_size(v->data_type) + sizeof(spl_val_t) - 1) /
|
usize nslots = (spl_type_size(v->data_type) + sizeof(spl_val_t) - 1) /
|
||||||
sizeof(spl_val_t);
|
sizeof(spl_val_t);
|
||||||
|
|||||||
@@ -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);
|
spl_tok_t *fname_tok = advance(ctx);
|
||||||
char fn_name[256];
|
char fn_name[256];
|
||||||
spl_tok_copy_name(fname_tok, fn_name, sizeof(fn_name));
|
spl_tok_copy_name(fname_tok, fn_name, sizeof(fn_name));
|
||||||
|
|
||||||
skip_nl(ctx);
|
skip_nl(ctx);
|
||||||
expect(ctx, TOK_L_PAREN);
|
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);
|
spl_tok_t *mname_tok = advance(ctx);
|
||||||
char mname[256];
|
char mname[256];
|
||||||
spl_tok_copy_name(mname_tok, mname, sizeof(mname));
|
spl_tok_copy_name(mname_tok, mname, sizeof(mname));
|
||||||
|
|
||||||
/* Build qualified name: TypeName.method_name */
|
/* Build qualified name: TypeName.method_name */
|
||||||
char qualified[512];
|
char qualified[512];
|
||||||
snprintf(qualified, sizeof(qualified), "%s.%s", container->name ? container->name : "anon",
|
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
|
* 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) {
|
static void parse_type_body(spl_comp_t *ctx, spl_type_info_t *container, int is_enum) {
|
||||||
if (peek(ctx)->type != TOK_L_BRACE)
|
if (peek(ctx)->type != TOK_L_BRACE)
|
||||||
return;
|
return;
|
||||||
@@ -265,8 +297,7 @@ static void parse_type_body(spl_comp_t *ctx, spl_type_info_t *container, int is_
|
|||||||
}
|
}
|
||||||
advance(ctx);
|
advance(ctx);
|
||||||
} else if (tt == KW_TYPE && depth == 1) {
|
} else if (tt == KW_TYPE && depth == 1) {
|
||||||
/* Nested type — already parsed in pass 1, skip */
|
skip_type_decl(ctx);
|
||||||
parse_type_decl(ctx);
|
|
||||||
} else if (tt == KW_VAR && depth == 1 && !is_enum) {
|
} else if (tt == KW_VAR && depth == 1 && !is_enum) {
|
||||||
/* var name: type; (struct/union only) */
|
/* var name: type; (struct/union only) */
|
||||||
advance(ctx); /* var */
|
advance(ctx); /* var */
|
||||||
@@ -426,7 +457,7 @@ void spl_parse_prog(spl_comp_t *ctx) {
|
|||||||
parse_fn_decl(ctx, 1, 0);
|
parse_fn_decl(ctx, 1, 0);
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
int prev = ctx->tok_idx;
|
int prev = ctx->tok_idx; /* Safety: prevent infinite loop */
|
||||||
/* Try to parse as a statement */
|
/* Try to parse as a statement */
|
||||||
spl_parse_stmt(ctx);
|
spl_parse_stmt(ctx);
|
||||||
/* Safety: prevent infinite loop on unrecognized tokens */
|
/* Safety: prevent infinite loop on unrecognized tokens */
|
||||||
|
|||||||
Reference in New Issue
Block a user