Merge pull request #6440 from dearblue/redo

Fix `redo` keyword
This commit is contained in:
Yukihiro "Matz" Matsumoto
2024-12-06 23:42:44 +09:00
committed by GitHub
2 changed files with 47 additions and 5 deletions
+10 -5
View File
@@ -1322,6 +1322,7 @@ for_body(codegen_scope *s, node *tree)
/* construct loop */
lp = loop_push(s, LOOP_FOR);
lp->pc1 = new_label(s);
genop_0(s, OP_NOP); /* for redo */
/* loop body */
codegen(s, tree->cdr->cdr->car, VAL);
@@ -2588,6 +2589,7 @@ codegen(codegen_scope *s, node *tree, int val)
pos = genjmp2_0(s, OP_JMPIF, cursp(), NOVAL);
}
lp->pc1 = new_label(s);
genop_0(s, OP_NOP); /* for redo */
codegen(s, tree->cdr, NOVAL);
genjmp(s, OP_JMP, lp->pc0);
dispatch(s, pos);
@@ -3182,11 +3184,14 @@ codegen(codegen_scope *s, node *tree, int val)
break;
case NODE_REDO:
if (!s->loop || s->loop->type == LOOP_BEGIN || s->loop->type == LOOP_RESCUE) {
raise_error(s, "unexpected redo");
}
else {
genjmp(s, OP_JMPUW, s->loop->pc1);
for (const struct loopinfo *lp = s->loop; ; lp = lp->prev) {
if (!lp) {
raise_error(s, "unexpected redo");
}
if (lp->type != LOOP_BEGIN && lp->type != LOOP_RESCUE) {
genjmp(s, OP_JMPUW, lp->pc1);
break;
}
}
if (val) push();
break;
+37
View File
@@ -95,6 +95,43 @@ assert('redo', '11.5.2.4.5') do
a.push(n)
end
assert_equal [1,3,4], a
a = []
limit = 3
e = RuntimeError.new("!")
for i in 0...3
begin
limit -= 1
break unless limit > 0
a.push i * 3 + 1
raise e
rescue
a.push i * 3 + 2
redo
ensure
a.push i * 3 + 3
end
end
assert_equal [1, 2, 3, 1, 2, 3, 3], a
a = []
limit = 3
e = RuntimeError.new("!")
for i in 0...3
a.push i * 4 + 1
begin
limit -= 1
break unless limit > 0
a.push i * 4 + 2
raise e
rescue
a.push i * 4 + 3
redo
ensure
a.push i * 4 + 4
end
end
assert_equal [1, 2, 3, 4, 1, 2, 3, 4, 1, 4], a
end
assert('Abbreviated variable assignment', '11.4.2.3.2') do