15
15
public final class NQPWhileNode extends NQPNode {
16
16
@ Child private LoopNode whileNode ;
17
17
18
+ public NQPWhileNode (boolean isUntil , NQPNode condNode , NQPNode bodyNode ) {
19
+ whileNode = Truffle .getRuntime ().createLoopNode (new WhileRepeatingNode (isUntil , condNode , bodyNode ));
20
+ }
21
+
18
22
@ Deserializer ("while" )
19
- public NQPWhileNode (NQPNode condNode , NQPNode bodyNode ) {
20
- whileNode = Truffle .getRuntime ().createLoopNode (new WhileRepeatingNode (condNode , bodyNode ));
23
+ public static NQPWhileNode createWhile (NQPNode condNode , NQPNode bodyNode ) {
24
+ return new NQPWhileNode (false , condNode , bodyNode );
25
+ }
26
+
27
+ @ Deserializer ("until" )
28
+ public static NQPWhileNode createUntil (NQPNode condNode , NQPNode bodyNode ) {
29
+ return new NQPWhileNode (true , condNode , bodyNode );
21
30
}
22
31
23
32
@ Override
@@ -32,17 +41,21 @@ public void executeVoid(VirtualFrame frame) {
32
41
}
33
42
34
43
private static class WhileRepeatingNode extends NQPNodeWithBoolification implements RepeatingNode {
44
+ private boolean isUntil ;
35
45
@ Child private NQPNode condNode ;
36
46
@ Child private NQPNode bodyNode ;
37
47
38
- public WhileRepeatingNode (NQPNode condNode , NQPNode bodyNode ) {
48
+ public WhileRepeatingNode (boolean isUntil , NQPNode condNode , NQPNode bodyNode ) {
49
+ this .isUntil = isUntil ;
39
50
this .condNode = condNode ;
40
51
this .bodyNode = bodyNode ;
41
52
}
42
53
43
54
@ Override
44
55
public boolean executeRepeating (VirtualFrame frame ) {
45
- if (toBoolean (condNode .execute (frame ))) {
56
+ boolean condResult = toBoolean (condNode .execute (frame ));
57
+ condResult = isUntil ? !condResult : condResult ;
58
+ if (condResult ) {
46
59
try {
47
60
bodyNode .executeVoid (frame );
48
61
} catch (ContinueException ex ) {
0 commit comments