stage1 支持label break, continue
This commit is contained in:
1 parent
3175e04e6e
commit
983746c797
5 files changed
+207
-36
No files matched your search
+67
-15
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user