// Path: lang/src/main/java/mumbler/truffle/MumblerLanguage.java
// @TruffleLanguage.Registration(id = ID, name = "Mumbler", version = "0.3",
//     characterMimeTypes = MumblerLanguage.MIME_TYPE, defaultMimeType = MumblerLanguage.MIME_TYPE)
// public class MumblerLanguage extends TruffleLanguage<Object> {
//     public static final String ID = "mumbler";
//     public static final String MIME_TYPE = "application/x-mumbler";
// 
//     private static final boolean TAIL_CALL_OPTIMIZATION_ENABLED = false;
// 
//     public MumblerLanguage() {
//     }
// 
//     @Override
//     protected Object createContext(TruffleLanguage.Env env) {
//         return new MumblerContext(this);
//     }
// 
//     @Override
//     protected CallTarget parse(ParsingRequest parsingRequest) throws IOException {
//         MumblerContext context = new MumblerContext(this);
//         ListSyntax sexp = Reader.read(parsingRequest.getSource());
//         Converter converter = new Converter(this, TAIL_CALL_OPTIMIZATION_ENABLED);
//         MumblerNode[] nodes = converter.convertSexp(context, sexp);
//         MumblerFunction function = MumblerFunction.create(this, new FrameSlot[] {},
//                 nodes, context.getGlobalFrame().getFrameDescriptor());
//         return function.callTarget;
//     }
// 
//     @Override
//     protected boolean isObjectOfLanguage(Object obj) {
//         return false;
//     }
// 
// }
// 
// Path: lang/src/main/java/mumbler/truffle/node/read/ReadArgumentNode.java
// public class ReadArgumentNode extends MumblerNode {
//     public final int argumentIndex;
// 
//     public ReadArgumentNode(int argumentIndex) {
//         this.argumentIndex = argumentIndex;
//     }
// 
//     @Override
//     public Object execute(VirtualFrame virtualFrame) {
//         if (!this.isArgumentIndexInRange(virtualFrame, this.argumentIndex)) {
//             CompilerDirectives.transferToInterpreterAndInvalidate();
//             throw new MumblerException("Not enough arguments passed. Missing " +
//                     (this.argumentIndex + 1) + "th argument");
//         }
//         return this.getArgument(virtualFrame, this.argumentIndex);
//     }
// 
//     @Override
//     public String toString() {
//         return "(arg " + this.argumentIndex + ")";
//     }
// }


import java.util.Arrays;
import mumbler.truffle.MumblerLanguage;
import mumbler.truffle.node.read.ReadArgumentNode;
import mumbler.truffle.node.special.DefineNodeGen;
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.RootNode;
package mumbler.truffle.node;




public class MumblerRootNode extends RootNode {
    @Children private final MumblerNode[] bodyNodes;
    @CompilationFinal public String name;

    public MumblerRootNode(MumblerLanguage lang, MumblerNode[] bodyNodes,
            FrameDescriptor frameDescriptor) {
        super(lang, frameDescriptor);
        this.bodyNodes = bodyNodes;
    }

    @Override
    @ExplodeLoop
    public Object execute(VirtualFrame virtualFrame) {
        int last = this.bodyNodes.length - 1;
        CompilerAsserts.compilationConstant(last);
        for (int i=0; i<last; i++) {
            this.bodyNodes[i].execute(virtualFrame);
        }
        return this.bodyNodes[last].execute(virtualFrame);
    }

    public static MumblerRootNode create(MumblerLanguage lang, FrameSlot[] argumentNames,
            MumblerNode[] bodyNodes, FrameDescriptor frameDescriptor) {
        MumblerNode[] allNodes = new MumblerNode[argumentNames.length
                                                 + bodyNodes.length];
        for (int i=0; i<argumentNames.length; i++) {
            allNodes[i] = DefineNodeGen.create(
// Path: lang/src/main/java/mumbler/truffle/MumblerLanguage.java
// @TruffleLanguage.Registration(id = ID, name = "Mumbler", version = "0.3",
//     characterMimeTypes = MumblerLanguage.MIME_TYPE, defaultMimeType = MumblerLanguage.MIME_TYPE)
// public class MumblerLanguage extends TruffleLanguage<Object> {
//     public static final String ID = "mumbler";
//     public static final String MIME_TYPE = "application/x-mumbler";
// 
//     private static final boolean TAIL_CALL_OPTIMIZATION_ENABLED = false;
// 
//     public MumblerLanguage() {
//     }
// 
//     @Override
//     protected Object createContext(TruffleLanguage.Env env) {
//         return new MumblerContext(this);
//     }
// 
//     @Override
//     protected CallTarget parse(ParsingRequest parsingRequest) throws IOException {
//         MumblerContext context = new MumblerContext(this);
//         ListSyntax sexp = Reader.read(parsingRequest.getSource());
//         Converter converter = new Converter(this, TAIL_CALL_OPTIMIZATION_ENABLED);
//         MumblerNode[] nodes = converter.convertSexp(context, sexp);
//         MumblerFunction function = MumblerFunction.create(this, new FrameSlot[] {},
//                 nodes, context.getGlobalFrame().getFrameDescriptor());
//         return function.callTarget;
//     }
// 
//     @Override
//     protected boolean isObjectOfLanguage(Object obj) {
//         return false;
//     }
// 
// }
// 
// Path: lang/src/main/java/mumbler/truffle/node/read/ReadArgumentNode.java
// public class ReadArgumentNode extends MumblerNode {
//     public final int argumentIndex;
// 
//     public ReadArgumentNode(int argumentIndex) {
//         this.argumentIndex = argumentIndex;
//     }
// 
//     @Override
//     public Object execute(VirtualFrame virtualFrame) {
//         if (!this.isArgumentIndexInRange(virtualFrame, this.argumentIndex)) {
//             CompilerDirectives.transferToInterpreterAndInvalidate();
//             throw new MumblerException("Not enough arguments passed. Missing " +
//                     (this.argumentIndex + 1) + "th argument");
//         }
//         return this.getArgument(virtualFrame, this.argumentIndex);
//     }
// 
//     @Override
//     public String toString() {
//         return "(arg " + this.argumentIndex + ")";
//     }
// }


// Path: lang/src/main/java/mumbler/truffle/node/MumblerRootNode.java
import java.util.Arrays;
import mumbler.truffle.MumblerLanguage;
import mumbler.truffle.node.read.ReadArgumentNode;
import mumbler.truffle.node.special.DefineNodeGen;
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.RootNode;

package mumbler.truffle.node;




public class MumblerRootNode extends RootNode {
    @Children private final MumblerNode[] bodyNodes;
    @CompilationFinal public String name;

    public MumblerRootNode(MumblerLanguage lang, MumblerNode[] bodyNodes,
            FrameDescriptor frameDescriptor) {
        super(lang, frameDescriptor);
        this.bodyNodes = bodyNodes;
    }

    @Override
    @ExplodeLoop
    public Object execute(VirtualFrame virtualFrame) {
        int last = this.bodyNodes.length - 1;
        CompilerAsserts.compilationConstant(last);
        for (int i=0; i<last; i++) {
            this.bodyNodes[i].execute(virtualFrame);
        }
        return this.bodyNodes[last].execute(virtualFrame);
    }

    public static MumblerRootNode create(MumblerLanguage lang, FrameSlot[] argumentNames,
            MumblerNode[] bodyNodes, FrameDescriptor frameDescriptor) {
        MumblerNode[] allNodes = new MumblerNode[argumentNames.length
                                                 + bodyNodes.length];
        for (int i=0; i<argumentNames.length; i++) {
            allNodes[i] = DefineNodeGen.create(
                    new ReadArgumentNode(i), argumentNames[i]);