package mumbler.truffle.node.special;
import mumbler.truffle.node.MumblerNode;
import mumbler.truffle.type.MumblerList;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
public class IfNode extends MumblerNode {
@Child private MumblerNode testNode;
@Child private MumblerNode thenNode;
@Child private MumblerNode elseNode;
private final ConditionProfile conditionProfile =
ConditionProfile.createBinaryProfile();
public IfNode(MumblerNode testNode, MumblerNode thenNode,
MumblerNode elseNode, SourceSection sourceSection) {
this.testNode = testNode;
this.thenNode = thenNode;
this.elseNode = elseNode;
setSourceSection(sourceSection);
}
@Override
public Object execute(VirtualFrame virtualFrame) {
if (this.conditionProfile.profile(this.testResult(virtualFrame))) {
return this.thenNode.execute(virtualFrame);
} else {
return this.elseNode.execute(virtualFrame);
}
}
@Override
public void setIsTail() {
super.setIsTail();
this.thenNode.setIsTail();
this.elseNode.setIsTail();
}
private boolean testResult(VirtualFrame virtualFrame) {
try {
return this.testNode.executeBoolean(virtualFrame);
} catch (UnexpectedResultException e) {
Object result = this.testNode.execute(virtualFrame);
return result != MumblerList.EMPTY;
}
}
@Override
public String toString() {
return "(if " + this.testNode + " " + this.elseNode + ")";
}
}