Skip to content

Commit

Permalink
[truffle] Implement nqp::until
Browse files Browse the repository at this point in the history
  • Loading branch information
pmurias committed Oct 24, 2019
1 parent f8da3a1 commit cb46cc8
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/vm/jvm/Truffle.nqp
Expand Up @@ -128,7 +128,7 @@ class QAST::OperationsTruffle {
return $comp.NYI("3 argument $op") if +@operands == 3 && $op ne 'while';

TAST.new($VOID, [
'while',
$op,
$comp.as_truffle(@operands[0], :want($OBJ)).tree,
$comp.as_truffle(@operands[1], :want($VOID)).tree
]);
Expand Down
Expand Up @@ -15,9 +15,18 @@
public final class NQPWhileNode extends NQPNode {
@Child private LoopNode whileNode;

public NQPWhileNode(boolean isUntil, NQPNode condNode, NQPNode bodyNode) {
whileNode = Truffle.getRuntime().createLoopNode(new WhileRepeatingNode(isUntil, condNode, bodyNode));
}

@Deserializer("while")
public NQPWhileNode(NQPNode condNode, NQPNode bodyNode) {
whileNode = Truffle.getRuntime().createLoopNode(new WhileRepeatingNode(condNode, bodyNode));
public static NQPWhileNode createWhile(NQPNode condNode, NQPNode bodyNode) {
return new NQPWhileNode(false, condNode, bodyNode);
}

@Deserializer("until")
public static NQPWhileNode createUntil(NQPNode condNode, NQPNode bodyNode) {
return new NQPWhileNode(true, condNode, bodyNode);
}

@Override
Expand All @@ -32,17 +41,21 @@ public void executeVoid(VirtualFrame frame) {
}

private static class WhileRepeatingNode extends NQPNodeWithBoolification implements RepeatingNode {
private boolean isUntil;
@Child private NQPNode condNode;
@Child private NQPNode bodyNode;

public WhileRepeatingNode(NQPNode condNode, NQPNode bodyNode) {
public WhileRepeatingNode(boolean isUntil, NQPNode condNode, NQPNode bodyNode) {
this.isUntil = isUntil;
this.condNode = condNode;
this.bodyNode = bodyNode;
}

@Override
public boolean executeRepeating(VirtualFrame frame) {
if (toBoolean(condNode.execute(frame))) {
boolean condResult = toBoolean(condNode.execute(frame));
condResult = isUntil ? !condResult : condResult;
if (condResult) {
try {
bodyNode.executeVoid(frame);
} catch (ContinueException ex) {
Expand Down

0 comments on commit cb46cc8

Please sign in to comment.