mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user