stage1 支持label break, continue

This commit is contained in:
zzy committed 2026-09-14 19:35:58 +08:00
1 parent 3175e04e6e
commit 983746c797
5 files changed
+207 -36

No files matched your search

+67 -15
View File
@@ -912,21 +912,6 @@ static void emit_stmt(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
}
return;
}
case SPL_AST_STATEMENT_BREAK: {
if (vec_size(a->loop_stack) == 0)
return;
spl_ir_node_ref_t jmp = spl_ir_builder_control_jmp(a->ir);
vec_push(vec_at(a->loop_stack, vec_size(a->loop_stack) - 1).breaks, jmp);
return;
}
case SPL_AST_STATEMENT_CONTINUE: {
if (vec_size(a->loop_stack) == 0)
return;
spl_ir_node_ref_t jmp = spl_ir_builder_control_jmp(a->ir);
usize cont = vec_at(a->loop_stack, vec_size(a->loop_stack) - 1).cont_blk;
spl_ir_builder_control_jmp_fixup(a->ir, jmp, cont);
return;
}
case SPL_AST_STATEMENT_DEFER:
if (n->statement_defer.body)
vec_push(a->defer_stack, n->statement_defer.body);
@@ -1041,6 +1026,12 @@ static void emit_stmt(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
spl_loop_ctx_t ctx = {0};
ctx.cont_blk = head_blk;
ctx.brk_blk = 0;
ctx.label = NULL;
if (n->while_expr.label) {
spl_ast_node_t *ln = spl_ast_node(a->sema->ast, n->while_expr.label);
if (ln && ln->kind == SPL_AST_LABEL)
ctx.label = ln->label.name;
}
vec_init(ctx.breaks);
vec_push(a->loop_stack, ctx);
@@ -1079,6 +1070,12 @@ static void emit_stmt(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
spl_loop_ctx_t ctx = {0};
ctx.cont_blk = head_blk;
ctx.brk_blk = 0;
ctx.label = NULL;
if (n->loop_expr.label) {
spl_ast_node_t *ln = spl_ast_node(a->sema->ast, n->loop_expr.label);
if (ln && ln->kind == SPL_AST_LABEL)
ctx.label = ln->label.name;
}
vec_init(ctx.breaks);
vec_push(a->loop_stack, ctx);
@@ -1103,6 +1100,61 @@ static void emit_stmt(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
vec_pop(a->loop_stack);
return;
}
case SPL_AST_STATEMENT_BREAK: {
if (vec_size(a->loop_stack) == 0)
return;
const char *lbl = NULL;
if (n->statement_break.label) {
spl_ast_node_t *ln = spl_ast_node(a->sema->ast, n->statement_break.label);
if (ln && ln->kind == SPL_AST_LABEL)
lbl = ln->label.name;
}
spl_ir_node_ref_t jmp = spl_ir_builder_control_jmp(a->ir);
if (lbl) {
for (usize i = vec_size(a->loop_stack); i > 0; --i) {
spl_loop_ctx_t *c = &vec_at(a->loop_stack, i - 1);
if (c->label && strcmp(c->label, lbl) == 0) {
vec_push(c->breaks, jmp);
return;
}
}
return;
}
vec_push(vec_at(a->loop_stack, vec_size(a->loop_stack) - 1).breaks, jmp);
return;
}
case SPL_AST_STATEMENT_CONTINUE: {
if (vec_size(a->loop_stack) == 0)
return;
const char *lbl = NULL;
if (n->statement_continue.label) {
spl_ast_node_t *ln = spl_ast_node(a->sema->ast, n->statement_continue.label);
if (ln && ln->kind == SPL_AST_LABEL)
lbl = ln->label.name;
}
spl_ir_node_ref_t jmp = spl_ir_builder_control_jmp(a->ir);
if (lbl) {
for (usize i = vec_size(a->loop_stack); i > 0; --i) {
spl_loop_ctx_t *c = &vec_at(a->loop_stack, i - 1);
if (c->label && strcmp(c->label, lbl) == 0) {
spl_ir_builder_control_jmp_fixup(a->ir, jmp, c->cont_blk);
return;
}
}
return;
}
usize cont = vec_at(a->loop_stack, vec_size(a->loop_stack) - 1).cont_blk;
spl_ir_builder_control_jmp_fixup(a->ir, jmp, cont);
return;
}
case SPL_AST_EXPR_BLOCK:
emit_expr(a, ref);
return;