// Path: lang/src/main/java/mumbler/truffle/node/MumblerNode.java
// @TypeSystemReference(MumblerTypes.class)
// @NodeInfo(language = "Mumbler Language", description = "The abstract base node for all expressions")
// public abstract class MumblerNode extends Node {
//     @CompilationFinal
//     private SourceSection sourceSection;
// 
//     @CompilationFinal
//     private boolean isTail = false;
// 
//     @Override
//     public SourceSection getSourceSection() {
//     	return this.sourceSection;
//     }
// 
//     public void setSourceSection(SourceSection sourceSection) {
//     	this.sourceSection = sourceSection;
//     }
// 
//     public boolean isTail() {
//         return this.isTail;
//     }
// 
//     public void setIsTail() {
//         this.isTail = true;
//     }
// 
//     public abstract Object execute(VirtualFrame virtualFrame);
// 
//     public long executeLong(VirtualFrame virtualFrame)
//             throws UnexpectedResultException {
//         return MumblerTypesGen.expectLong(this.execute(virtualFrame));
//     }
// 
//     public boolean executeBoolean(VirtualFrame virtualFrame)
//             throws UnexpectedResultException {
//         return MumblerTypesGen.expectBoolean(this.execute(virtualFrame));
//     }
// 
//     public BigInteger executeBigInteger(VirtualFrame virtualFrame)
//             throws UnexpectedResultException {
//         return MumblerTypesGen.expectBigInteger(this.execute(virtualFrame));
//     }
// 
//     public MumblerSymbol executeMumblerSymbol(VirtualFrame virtualFrame)
//             throws UnexpectedResultException {
//         return MumblerTypesGen.expectMumblerSymbol(this.execute(virtualFrame));
//     }
// 
//     public MumblerFunction executeMumblerFunction(VirtualFrame virtualFrame)
//             throws UnexpectedResultException {
//         return MumblerTypesGen.expectMumblerFunction(
//                 this.execute(virtualFrame));
//     }
// 
//     public MumblerList<?> executeMumblerList(VirtualFrame virtualFrame)
//             throws UnexpectedResultException {
//         return MumblerTypesGen.expectMumblerList(this.execute(virtualFrame));
//     }
// 
//     public String executeString(VirtualFrame virtualFrame)
//             throws UnexpectedResultException{
//         return MumblerTypesGen.expectString(this.execute(virtualFrame));
//     }
// 
//     protected boolean isArgumentIndexInRange(VirtualFrame virtualFrame,
//             int index) {
//         return (index + 1) < virtualFrame.getArguments().length;
//     }
// 
//     protected Object getArgument(VirtualFrame virtualFrame, int index) {
//         return virtualFrame.getArguments()[index + 1];
//     }
// 
//     protected static MaterializedFrame getLexicalScope(Frame frame) {
//         Object[] args = frame.getArguments();
//         if (args.length > 0) {
//             return (MaterializedFrame) frame.getArguments()[0];
//         } else {
//             return null;
//         }
//     }
// }
// 
// Path: lang/src/main/java/mumbler/truffle/node/call/InvokeNode.java
// public class InvokeNode extends MumblerNode {
//     @Child protected MumblerNode functionNode;
//     @Children protected final MumblerNode[] argumentNodes;
//     @Child protected DispatchNode dispatchNode;
// 
//     public InvokeNode(MumblerNode functionNode, MumblerNode[] argumentNodes,
//             SourceSection sourceSection) {
//         this.functionNode = functionNode;
//         this.argumentNodes = argumentNodes;
//         this.dispatchNode = new UninitializedDispatchNode();
//         setSourceSection(sourceSection);
//     }
// 
//     @Override
//     @ExplodeLoop
//     public Object execute(VirtualFrame virtualFrame) {
//         MumblerFunction function = this.evaluateFunction(virtualFrame);
//         CompilerAsserts.compilationConstant(this.argumentNodes.length);
//         CompilerAsserts.compilationConstant(this.isTail());
// 
//         Object[] argumentValues = new Object[this.argumentNodes.length + 1];
//         argumentValues[0] = function.getLexicalScope();
//         for (int i=0; i<this.argumentNodes.length; i++) {
//             argumentValues[i+1] = this.argumentNodes[i].execute(virtualFrame);
//         }
// 
//         return call(virtualFrame, function.callTarget, argumentValues);
//     }
// 
//     protected Object call(VirtualFrame virtualFrame, CallTarget callTarget,
//             Object[] arguments) {
//         return this.dispatchNode.executeDispatch(virtualFrame,
//                 callTarget, arguments);
//     }
// 
//     private MumblerFunction evaluateFunction(VirtualFrame virtualFrame) {
//         try {
//             return this.functionNode.executeMumblerFunction(virtualFrame);
//         } catch (UnexpectedResultException e) {
//             throw new UnsupportedSpecializationException(this,
//                     new Node[] {this.functionNode}, e);
//         }
//     }
// 
//     @Override
//     public String toString() {
//         return "(apply " + this.functionNode + " " +
//                 Arrays.toString(this.argumentNodes) + ")";
//     }
// }


import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.NodeInfo;
import mumbler.truffle.node.MumblerNode;
import mumbler.truffle.node.call.InvokeNode;
package mumbler.truffle.node.special;



@NodeInfo(shortName = "loop", description = "Repeats the function call forever")
public class LoopNode extends MumblerNode {
    @Child private com.oracle.truffle.api.nodes.LoopNode loopNode;
    private final String callString;

// Path: lang/src/main/java/mumbler/truffle/node/MumblerNode.java
// @TypeSystemReference(MumblerTypes.class)
// @NodeInfo(language = "Mumbler Language", description = "The abstract base node for all expressions")
// public abstract class MumblerNode extends Node {
//     @CompilationFinal
//     private SourceSection sourceSection;
// 
//     @CompilationFinal
//     private boolean isTail = false;
// 
//     @Override
//     public SourceSection getSourceSection() {
//     	return this.sourceSection;
//     }
// 
//     public void setSourceSection(SourceSection sourceSection) {
//     	this.sourceSection = sourceSection;
//     }
// 
//     public boolean isTail() {
//         return this.isTail;
//     }
// 
//     public void setIsTail() {
//         this.isTail = true;
//     }
// 
//     public abstract Object execute(VirtualFrame virtualFrame);
// 
//     public long executeLong(VirtualFrame virtualFrame)
//             throws UnexpectedResultException {
//         return MumblerTypesGen.expectLong(this.execute(virtualFrame));
//     }
// 
//     public boolean executeBoolean(VirtualFrame virtualFrame)
//             throws UnexpectedResultException {
//         return MumblerTypesGen.expectBoolean(this.execute(virtualFrame));
//     }
// 
//     public BigInteger executeBigInteger(VirtualFrame virtualFrame)
//             throws UnexpectedResultException {
//         return MumblerTypesGen.expectBigInteger(this.execute(virtualFrame));
//     }
// 
//     public MumblerSymbol executeMumblerSymbol(VirtualFrame virtualFrame)
//             throws UnexpectedResultException {
//         return MumblerTypesGen.expectMumblerSymbol(this.execute(virtualFrame));
//     }
// 
//     public MumblerFunction executeMumblerFunction(VirtualFrame virtualFrame)
//             throws UnexpectedResultException {
//         return MumblerTypesGen.expectMumblerFunction(
//                 this.execute(virtualFrame));
//     }
// 
//     public MumblerList<?> executeMumblerList(VirtualFrame virtualFrame)
//             throws UnexpectedResultException {
//         return MumblerTypesGen.expectMumblerList(this.execute(virtualFrame));
//     }
// 
//     public String executeString(VirtualFrame virtualFrame)
//             throws UnexpectedResultException{
//         return MumblerTypesGen.expectString(this.execute(virtualFrame));
//     }
// 
//     protected boolean isArgumentIndexInRange(VirtualFrame virtualFrame,
//             int index) {
//         return (index + 1) < virtualFrame.getArguments().length;
//     }
// 
//     protected Object getArgument(VirtualFrame virtualFrame, int index) {
//         return virtualFrame.getArguments()[index + 1];
//     }
// 
//     protected static MaterializedFrame getLexicalScope(Frame frame) {
//         Object[] args = frame.getArguments();
//         if (args.length > 0) {
//             return (MaterializedFrame) frame.getArguments()[0];
//         } else {
//             return null;
//         }
//     }
// }
// 
// Path: lang/src/main/java/mumbler/truffle/node/call/InvokeNode.java
// public class InvokeNode extends MumblerNode {
//     @Child protected MumblerNode functionNode;
//     @Children protected final MumblerNode[] argumentNodes;
//     @Child protected DispatchNode dispatchNode;
// 
//     public InvokeNode(MumblerNode functionNode, MumblerNode[] argumentNodes,
//             SourceSection sourceSection) {
//         this.functionNode = functionNode;
//         this.argumentNodes = argumentNodes;
//         this.dispatchNode = new UninitializedDispatchNode();
//         setSourceSection(sourceSection);
//     }
// 
//     @Override
//     @ExplodeLoop
//     public Object execute(VirtualFrame virtualFrame) {
//         MumblerFunction function = this.evaluateFunction(virtualFrame);
//         CompilerAsserts.compilationConstant(this.argumentNodes.length);
//         CompilerAsserts.compilationConstant(this.isTail());
// 
//         Object[] argumentValues = new Object[this.argumentNodes.length + 1];
//         argumentValues[0] = function.getLexicalScope();
//         for (int i=0; i<this.argumentNodes.length; i++) {
//             argumentValues[i+1] = this.argumentNodes[i].execute(virtualFrame);
//         }
// 
//         return call(virtualFrame, function.callTarget, argumentValues);
//     }
// 
//     protected Object call(VirtualFrame virtualFrame, CallTarget callTarget,
//             Object[] arguments) {
//         return this.dispatchNode.executeDispatch(virtualFrame,
//                 callTarget, arguments);
//     }
// 
//     private MumblerFunction evaluateFunction(VirtualFrame virtualFrame) {
//         try {
//             return this.functionNode.executeMumblerFunction(virtualFrame);
//         } catch (UnexpectedResultException e) {
//             throw new UnsupportedSpecializationException(this,
//                     new Node[] {this.functionNode}, e);
//         }
//     }
// 
//     @Override
//     public String toString() {
//         return "(apply " + this.functionNode + " " +
//                 Arrays.toString(this.argumentNodes) + ")";
//     }
// }


// Path: lang/src/main/java/mumbler/truffle/node/special/LoopNode.java
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.NodeInfo;
import mumbler.truffle.node.MumblerNode;
import mumbler.truffle.node.call.InvokeNode;

package mumbler.truffle.node.special;



@NodeInfo(shortName = "loop", description = "Repeats the function call forever")
public class LoopNode extends MumblerNode {
    @Child private com.oracle.truffle.api.nodes.LoopNode loopNode;
    private final String callString;

    public LoopNode(InvokeNode callNode) {