Skip to content

Commit e580275

Browse files
committed
fix breaking out of an else of a loop and add test
1 parent 853b63b commit e580275

File tree

4 files changed

+54
-14
lines changed

4 files changed

+54
-14
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_for.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,29 @@ def test_else_continue():
8686
continue
8787

8888
assert ["continue", "break"] == sequence
89+
90+
91+
def test_else_break():
92+
iters = 0
93+
while iters < 4:
94+
for i in range(iters):
95+
if False:
96+
break
97+
iters += 1
98+
else:
99+
iters += 1
100+
break
101+
assert iters == 2, "if the for-loop doesn't break, the else should be executed and break out of the outer loop"
102+
103+
104+
def test_else_break():
105+
iters = 0
106+
while iters < 40:
107+
while iters < 10:
108+
if False:
109+
break
110+
iters += 1
111+
else:
112+
iters += 1
113+
break
114+
assert iters == 11, "if the while-loop doesn't break, the else should be executed and break out of the outer loop"

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/NodeFactory.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,11 @@ public StatementNode createContinueTarget(StatementNode child) {
209209
}
210210

211211
public StatementNode createBreakTarget(StatementNode forNode) {
212-
return new BreakTargetNode(forNode);
212+
return new BreakTargetNode(forNode, null);
213+
}
214+
215+
public StatementNode createBreakTarget(StatementNode forNode, StatementNode orelse) {
216+
return new BreakTargetNode(forNode, orelse);
213217
}
214218

215219
public YieldNode createYield(ExpressionNode right, FrameSlot returnSlot) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/control/BreakTargetNode.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@ public final class BreakTargetNode extends StatementNode {
3636
private final BranchProfile defaultExitProfile = BranchProfile.create();
3737

3838
@Child private StatementNode statement;
39+
@Child private StatementNode orelse;
3940

40-
public BreakTargetNode(StatementNode statement) {
41+
public BreakTargetNode(StatementNode statement, StatementNode orelse) {
4142
this.statement = statement;
43+
this.orelse = orelse;
4244
}
4345

4446
public StatementNode getStatement() {
@@ -52,6 +54,10 @@ public void executeVoid(VirtualFrame frame) {
5254
defaultExitProfile.enter();
5355
} catch (BreakException ex) {
5456
breakProfile.enter();
57+
return;
58+
}
59+
if (orelse != null) {
60+
orelse.executeVoid(frame);
5561
}
5662
}
5763
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/PythonTreeTranslator.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,15 +1255,17 @@ private PNode createWhileNode(PNode test, StatementNode body, StatementNode orel
12551255
StatementNode whileNode = factory.createWhile(factory.toBooleanCastNode(test), wrappedBody);
12561256
// assignSourceFromNode(node, whileNode);
12571257

1258-
if (!EmptyNode.isEmpty(orelse)) {
1258+
if (info.hasBreak()) {
1259+
if (!EmptyNode.isEmpty(orelse)) {
1260+
whileNode = factory.createBreakTarget(whileNode, orelse);
1261+
} else {
1262+
whileNode = factory.createBreakTarget(whileNode);
1263+
}
1264+
} else if (!EmptyNode.isEmpty(orelse)) {
12591265
whileNode = factory.createElse(whileNode, orelse);
12601266
}
12611267

1262-
if (info.hasBreak()) {
1263-
return factory.createBreakTarget(whileNode);
1264-
} else {
1265-
return whileNode;
1266-
}
1268+
return whileNode;
12671269
}
12681270

12691271
@Override
@@ -1288,15 +1290,17 @@ private StatementNode createForNode(StatementNode target, ExpressionNode iter, S
12881290
StatementNode forNode = createForInScope(target, iter, wrappedBody);
12891291
// assignSourceFromNode(node, forNode);
12901292

1291-
if (!EmptyNode.isEmpty(orelse)) {
1293+
if (info.hasBreak()) {
1294+
if (!EmptyNode.isEmpty(orelse)) {
1295+
forNode = factory.createBreakTarget(forNode, orelse);
1296+
} else {
1297+
forNode = factory.createBreakTarget(forNode);
1298+
}
1299+
} else if (!EmptyNode.isEmpty(orelse)) {
12921300
forNode = factory.createElse(forNode, orelse);
12931301
}
12941302

1295-
if (info.hasBreak()) {
1296-
return factory.createBreakTarget(forNode);
1297-
} else {
1298-
return forNode;
1299-
}
1303+
return forNode;
13001304
}
13011305

13021306
private LoopNode createForInScope(StatementNode target, ExpressionNode iterator, StatementNode body) {

0 commit comments

Comments
 (0)