Package st.gravel.support.compiler.jvm

Source Code of st.gravel.support.compiler.jvm.JVMMethodCompiler$JVMMethodCompiler_Factory

package st.gravel.support.compiler.jvm;

/*
  This file is automatically generated from typed smalltalk source. Do not edit by hand.
  (C) AG5.com
*/

import java.math.BigInteger;
import st.gravel.support.jvm.NonLocalReturn;
import st.gravel.support.compiler.ast.NodeVisitor;
import st.gravel.support.compiler.ast.NodeVisitor.NodeVisitor_Factory;
import st.gravel.support.compiler.jvm.JVMClassCompiler;
import java.util.Map;
import st.gravel.support.compiler.jvm.JVMLocalDeclaration;
import st.gravel.support.compiler.jvm.JVMStack;
import java.util.List;
import st.gravel.support.compiler.jvm.JVMInstruction;
import st.gravel.support.compiler.jvm.JVMMethodType;
import st.gravel.support.compiler.jvm.JVMField;
import st.gravel.support.compiler.jvm.BlockSendArgument;
import st.gravel.support.compiler.ast.BlockNode;
import st.gravel.support.compiler.jvm.JVMDefinedObjectType;
import st.gravel.support.compiler.jvm.JVMMethod;
import java.util.HashMap;
import st.gravel.support.compiler.ast.VariableDeclarationNode;
import st.gravel.support.compiler.jvm.JVMVariable;
import st.gravel.support.compiler.ast.NonLocalVariableFinder;
import st.gravel.support.compiler.jvm.BlockInnerClass;
import st.gravel.support.compiler.jvm.JVMType;
import st.gravel.support.compiler.ast.SourcePosition;
import st.gravel.support.compiler.jvm.Store;
import st.gravel.support.compiler.jvm.Frame;
import java.util.ArrayList;
import st.gravel.support.compiler.ast.SequenceNode;
import st.gravel.support.compiler.jvm.JVMDynamicObjectType;
import st.gravel.support.compiler.jvm.AReturn;
import st.gravel.support.compiler.ast.MessageNode;
import st.gravel.support.compiler.ast.Node;
import st.gravel.support.compiler.jvm.DynamicLiteralBlockMessageSend;
import st.gravel.support.compiler.ast.Expression;
import st.gravel.support.compiler.jvm.JVMMethodConstant;
import st.gravel.support.compiler.jvm.DynamicMessageSend;
import st.gravel.support.compiler.ast.Statement;
import st.gravel.support.compiler.jvm.Pop;
import st.gravel.support.compiler.ast.MethodNode;
import st.gravel.support.compiler.jvm.NewInstance;
import st.gravel.support.compiler.jvm.Dup;
import st.gravel.support.compiler.jvm.InvokeSpecial;
import st.gravel.support.compiler.jvm.GetField;
import st.gravel.support.compiler.jvm.IfObjectsEqualThenElse;
import st.gravel.support.compiler.jvm.AThrow;
import st.gravel.support.compiler.jvm.Invoke;
import st.gravel.support.compiler.jvm.WhileTrueLoop;
import st.gravel.support.compiler.jvm.JVMBooleanType;
import st.gravel.support.compiler.ast.SuperNode;
import st.gravel.support.compiler.jvm.InvokeStatic;
import st.gravel.support.compiler.jvm.DynamicSuperSend;
import st.gravel.support.compiler.ast.ToDoNode;
import st.gravel.support.compiler.jvm.JVMIntType;
import st.gravel.support.compiler.jvm.IncrementLocal;
import st.gravel.support.compiler.jvm.WhileLessThanLoop;
import st.gravel.support.compiler.jvm.WhileGreaterThanLoop;
import st.gravel.support.compiler.jvm.Load;
import st.gravel.support.compiler.jvm.PushTrue;
import st.gravel.support.compiler.jvm.PushFalse;
import st.gravel.support.compiler.jvm.NewArray;
import st.gravel.support.compiler.jvm.JVMByteType;
import st.gravel.support.compiler.jvm.ByteArrayStore;
import st.gravel.support.compiler.jvm.PushChar;
import st.gravel.support.compiler.jvm.PushDouble;
import st.gravel.support.compiler.jvm.PushFloat;
import st.gravel.support.compiler.jvm.PushInt;
import st.gravel.support.compiler.jvm.PushNull;
import st.gravel.support.compiler.jvm.PushString;
import st.gravel.support.compiler.jvm.TryCatch;
import st.gravel.support.compiler.jvm.LabelLineNumber;
import st.gravel.support.compiler.ast.ArrayAtNode;
import st.gravel.support.compiler.jvm.JVMArrayType;
import st.gravel.support.compiler.jvm.Subtract;
import st.gravel.support.compiler.jvm.ObjectArrayLoad;
import st.gravel.support.compiler.ast.ArrayAtPutNode;
import st.gravel.support.compiler.jvm.DupX2;
import st.gravel.support.compiler.jvm.ObjectArrayStore;
import st.gravel.support.compiler.ast.ArrayLiteralNode;
import st.gravel.support.compiler.ast.ArraySizeNode;
import st.gravel.support.compiler.jvm.ArrayLength;
import st.gravel.support.compiler.ast.BooleanAndNode;
import st.gravel.support.compiler.jvm.AndThenElse;
import st.gravel.support.compiler.ast.BooleanLiteralNode;
import st.gravel.support.compiler.ast.BooleanOrNode;
import st.gravel.support.compiler.jvm.OrThenElse;
import st.gravel.support.compiler.ast.ByteArrayLiteralNode;
import st.gravel.support.compiler.ast.CascadeNode;
import st.gravel.support.compiler.ast.CharacterLiteralNode;
import st.gravel.support.compiler.ast.CreateHolderNode;
import st.gravel.support.compiler.ast.DoubleLiteralNode;
import st.gravel.support.compiler.ast.FieldReadNode;
import st.gravel.support.compiler.jvm.DynamicFieldRead;
import st.gravel.support.compiler.jvm.TypeNodeToJVMTypeConverter;
import st.gravel.support.compiler.ast.FieldWriteNode;
import st.gravel.support.compiler.jvm.DupX1;
import st.gravel.support.compiler.jvm.DynamicFieldWrite;
import st.gravel.support.compiler.ast.FixedPointLiteralNode;
import st.gravel.support.compiler.ast.FloatLiteralNode;
import st.gravel.support.compiler.ast.GlobalReadNode;
import st.gravel.support.compiler.jvm.DynamicGlobalRead;
import st.gravel.support.compiler.ast.GlobalWriteNode;
import st.gravel.support.compiler.jvm.DynamicGlobalWrite;
import st.gravel.support.compiler.ast.HolderDeclarationNode;
import st.gravel.support.compiler.ast.IdentityComparisonNode;
import st.gravel.support.compiler.ast.BinaryMessageNode;
import st.gravel.support.compiler.ast.IfTrueIfFalseNode;
import st.gravel.support.compiler.jvm.IfThenElse;
import st.gravel.support.compiler.ast.InlineExpressionCollection;
import st.gravel.support.compiler.ast.InstanceCreationNode;
import st.gravel.support.compiler.jvm.DynamicCreateInstance;
import st.gravel.support.compiler.ast.IntegerLiteralNode;
import st.gravel.support.compiler.ast.IsNilNode;
import st.gravel.support.compiler.jvm.IfObjectIsNullThenElse;
import st.gravel.support.compiler.ast.LocalReadNode;
import st.gravel.support.compiler.ast.LocalWriteNode;
import st.gravel.support.compiler.ast.NamespacedVariableNode;
import st.gravel.support.compiler.ast.NilLiteralNode;
import st.gravel.support.compiler.ast.NonLocalReturnNode;
import st.gravel.support.compiler.ast.ReadHolderNode;
import st.gravel.support.compiler.ast.ReferenceLiteralNode;
import st.gravel.support.compiler.ast.ReturnNode;
import st.gravel.support.compiler.ast.SelfNode;
import st.gravel.support.compiler.ast.StringLiteralNode;
import st.gravel.support.compiler.ast.SymbolLiteralNode;
import st.gravel.support.compiler.ast.TypeCast;
import st.gravel.support.compiler.ast.WhileFalseNode;
import st.gravel.support.compiler.jvm.WhileFalseLoop;
import st.gravel.support.compiler.ast.WhileTrueNode;
import st.gravel.support.compiler.ast.WriteHolderNode;

public class JVMMethodCompiler extends NodeVisitor<Object> implements Cloneable {

  public static JVMMethodCompiler_Factory factory = new JVMMethodCompiler_Factory();

  Map<String, JVMField> _copiedVariables;

  String _copiedVariablesOwner;

  List<JVMInstruction> _instructions;

  boolean _isBlock;

  boolean _isStatic;

  Map<String, JVMLocalDeclaration> _locals;

  String _methodName;

  JVMClassCompiler _parent;

  JVMMethodType _signature;

  JVMStack _stack;

  int _temp;

  public static class JVMMethodCompiler_Factory extends NodeVisitor_Factory<Object> {

    public JVMMethodCompiler basicNew() {
      JVMMethodCompiler newInstance = new JVMMethodCompiler();
      newInstance.initialize();
      return newInstance;
    }

    public JVMMethodCompiler parent_(final JVMClassCompiler _aJVMClassCompiler) {
      return this.basicNew().initializeParent_(_aJVMClassCompiler);
    }
  }

  static public JVMMethodCompiler _parent_(Object receiver, final JVMClassCompiler _aJVMClassCompiler) {
    return factory.parent_(_aJVMClassCompiler);
  }

  public String addASTConstant_(final BlockSendArgument _aBlockSendArgument) {
    return _parent.addASTConstant_(_aBlockSendArgument);
  }

  public JVMMethod buildBlock_copiedVariables_blockType_(final BlockNode _aBlockNode, final JVMField[] _anArray, final JVMDefinedObjectType _blockType) {
    final int _numArgs;
    this.reset();
    _isBlock = true;
    _copiedVariables = new java.util.HashMap<String, JVMField>();
    for (final JVMField _each : _anArray) {
      _copiedVariables.put(_each.varName(), _each);
    }
    _copiedVariablesOwner = this.newTempName();
    this.pushLocal_type_(_copiedVariablesOwner, _blockType);
    for (final VariableDeclarationNode _each : _aBlockNode.arguments()) {
      JVMMethodCompiler.this.pushLocal_(_each.name());
    }
    this.produceBlockBody_(_aBlockNode.body());
    _numArgs = _aBlockNode.arguments().length;
    _methodName = _parent.selectorConverter().functionNameForNumArgs_(_numArgs);
    _signature = JVMMethodType.factory.dynamic_(_numArgs);
    return this.buildMethod();
  }

  public JVMMethod buildMethod() {
    return JVMMethod.factory.name_locals_instructions_isStatic_signature_(_methodName, _locals.values().toArray(new JVMLocalDeclaration[_locals.size()]), _instructions.toArray(new JVMInstruction[_instructions.size()]), _isStatic, _signature);
  }

  public JVMVariable[] copiedVariablesForBlockNode_(final BlockNode _blockNode) {
    return st.gravel.support.jvm.ArrayExtensions.collect_(st.gravel.support.jvm.ArrayExtensions.asSortedArray(NonLocalVariableFinder.factory.analyze_(_blockNode)), ((st.gravel.support.jvm.Block1<JVMVariable, String>) (new st.gravel.support.jvm.Block1<JVMVariable, String>() {

      @Override
      public JVMVariable value_(final String _each) {
        return (JVMVariable) JVMMethodCompiler.this.localOrCopiedAt_(_each);
      }
    })));
  }

  public JVMMethodCompiler copy() {
    try {
      JVMMethodCompiler _temp1 = (JVMMethodCompiler) this.clone();
      _temp1.postCopy();
      return _temp1;
    } catch (CloneNotSupportedException e) {
      throw new RuntimeException(e);
    }
  }

  public BlockInnerClass createBlockInnerClass_copiedVariables_(final BlockNode _aBlockNode, final JVMVariable[] _anArray) {
    return _parent.createBlockInnerClass_copiedVariables_(_aBlockNode, _anArray);
  }

  public JVMMethodCompiler emit_(final JVMInstruction _anInstruction) {
    _instructions.add(_anInstruction.effectStack_(_stack));
    return this;
  }

  public JVMMethodCompiler ensureCast_(final JVMType _aType) {
    final JVMType _lastType;
    JVMType _temp1 = _lastType = _stack.peek();
    if (!st.gravel.support.jvm.ObjectExtensions.equals_(_temp1, _aType)) {
      JVMMethodCompiler.this.emit_(_lastType.newCastInstructionTo_(_aType));
    }
    return this;
  }

  public JVMMethodCompiler_Factory factory() {
    return factory;
  }

  @Override
  public JVMMethodCompiler initialize() {
    _isBlock = false;
    _temp = 0;
    if (_parent != null) {
      _isStatic = _parent.isStatic();
    }
    return this;
  }

  public JVMMethodCompiler initializeParent_(final JVMClassCompiler _aJVMClassCompiler) {
    _parent = _aJVMClassCompiler;
    this.initialize();
    return this;
  }

  public boolean isStatic() {
    return _isStatic;
  }

  public JVMMethodCompiler isStatic_(final boolean _anObject) {
    _isStatic = _anObject;
    return this;
  }

  public Integer lineNumberOf_(final SourcePosition _aSourcePosition) {
    return _parent.lineNumberOf_(_aSourcePosition);
  }

  public JVMVariable localOrCopiedAt_(final String _varName) {
    final JVMLocalDeclaration _local;
    JVMLocalDeclaration _temp1 = _locals.get(_varName);
    _local = ((JVMLocalDeclaration) _temp1);
    if (_local != null) {
      return _local;
    }
    return _copiedVariables.get(_varName);
  }

  public JVMMethodCompiler localStore_(final String _localName) {
    final JVMLocalDeclaration _local;
    _local = _locals.get(_localName);
    this.ensureCast_(_local.type());
    this.emit_(((JVMInstruction) Store.factory.local_(_local)));
    return this;
  }

  public Frame newFrame_(final st.gravel.support.jvm.Block0<Object> _aBlock) {
    final JVMStack _oldStack;
    final List<JVMInstruction> _oldInstructions;
    final Frame _frame;
    final Map<String, JVMLocalDeclaration> _oldLocals;
    _oldStack = _stack;
    _oldInstructions = _instructions;
    _oldLocals = _locals;
    this.reset();
    _locals = st.gravel.support.jvm.DictionaryExtensions.copy(_oldLocals);
    _aBlock.value();
    _frame = Frame.factory.instructions_endStack_(_instructions.toArray(new JVMInstruction[_instructions.size()]), _stack);
    _stack = _oldStack;
    _instructions = _oldInstructions;
    _locals = _oldLocals;
    return _frame;
  }

  public Frame newSubFrame_(final st.gravel.support.jvm.Block0<Object> _aBlock) {
    final JVMStack _oldStack;
    final List<JVMInstruction> _oldInstructions;
    final Frame _frame;
    final Map<String, JVMLocalDeclaration> _oldLocals;
    _oldStack = _stack;
    _oldInstructions = _instructions;
    _oldLocals = _locals;
    _locals = st.gravel.support.jvm.DictionaryExtensions.copy(_oldLocals);
    _instructions = new java.util.ArrayList();
    _stack = _oldStack.copy();
    _aBlock.value();
    _frame = Frame.factory.instructions_endStack_(_instructions.toArray(new JVMInstruction[_instructions.size()]), _stack);
    _stack = _oldStack;
    _instructions = _oldInstructions;
    _locals = _oldLocals;
    return _frame;
  }

  public String newTempName() {
    return "_temp" + "" + ++_temp;
  }

  public JVMDefinedObjectType ownerType() {
    return _parent.ownerType();
  }

  public JVMClassCompiler parent() {
    return _parent;
  }

  public JVMMethodCompiler produceBlockBody_(final SequenceNode _body) {
    this.visit_(_body);
    if (_stack.isEmpty()) {
      JVMMethodCompiler.this.pushNull();
    }
    this.ensureCast_(JVMDynamicObjectType.factory.basicNew());
    this.emit_(AReturn.factory.basicNew());
    return this;
  }

  public JVMMethodCompiler produceBlockInlineMessageSend_(final MessageNode _messageNode) {
    final st.gravel.core.Symbol _selector;
    final String[][] _blockSendConstants;
    final int[] _passedNumArgs;
    final JVMVariable[][] _argumentsToCopy;
    _argumentsToCopy = new JVMVariable[1][];
    _blockSendConstants = new String[1][];
    _passedNumArgs = new int[1];
    _blockSendConstants[0] = new String[] {};
    _argumentsToCopy[0] = new JVMVariable[] {};
    _passedNumArgs[0] = 0;
    for (final Node _arg : _messageNode.arguments()) {
      if (_arg.isBlockNode()) {
        final BlockNode _blockNode;
        final JVMVariable[] _nCopiedVariables;
        _blockNode = ((BlockNode) _arg);
        _nCopiedVariables = JVMMethodCompiler.this.copiedVariablesForBlockNode_(_blockNode);
        for (final JVMVariable _each : _nCopiedVariables) {
          if (!st.gravel.support.jvm.ArrayExtensions.includes_(_argumentsToCopy[0], _each)) {
            _argumentsToCopy[0] = st.gravel.support.jvm.ArrayExtensions.copyWith_(_argumentsToCopy[0], _each);
          }
        }
        _blockSendConstants[0] = st.gravel.support.jvm.ArrayExtensions.copyWith_(_blockSendConstants[0], JVMMethodCompiler.this.addASTConstant_(BlockSendArgument.factory.blockNode_copiedVariables_(_blockNode, _nCopiedVariables)));
      } else {
        _passedNumArgs[0] = ((_passedNumArgs[0]) + 1);
        JVMMethodCompiler.this.visit_(_arg);
        JVMMethodCompiler.this.ensureCast_(JVMDynamicObjectType.factory.basicNew());
        _blockSendConstants[0] = st.gravel.support.jvm.ArrayExtensions.copyWith_(_blockSendConstants[0], null);
      }
    }
    for (final JVMVariable _each : _argumentsToCopy[0]) {
      JVMMethodCompiler.this.produceVarRead_(_each.varName());
      JVMMethodCompiler.this.ensureCast_(_each.type());
    }
    _selector = st.gravel.core.Symbol.value(_messageNode.selector());
    this.emit_(DynamicLiteralBlockMessageSend.factory.functionName_numArgs_blockSendConstants_constantOwner_copiedArguments_(_parent.selectorConverter().selectorAsFunctionName_(_selector), ((_passedNumArgs[0]) + _argumentsToCopy[0].length), _blockSendConstants[0], _parent.ownerType(), st.gravel.support.jvm.ArrayExtensions.collect_(_argumentsToCopy[0], ((st.gravel.support.jvm.Block1<String, JVMVariable>) (new st.gravel.support.jvm.Block1<String, JVMVariable>() {

      @Override
      public String value_(final JVMVariable _each) {
        return (String) _each.varName();
      }
    })))));
    return this;
  }

  public JVMMethodCompiler produceConstant_ifAbsentPut_(final Expression _anExpression, final st.gravel.support.jvm.Block0<Object> _aBlock) {
    final JVMMethodConstant _const;
    _const = _parent.constantAt_ifAbsentPut_(_anExpression, ((st.gravel.support.jvm.Block0<JVMMethodConstant>) (new st.gravel.support.jvm.Block0<JVMMethodConstant>() {

      @Override
      public JVMMethodConstant value() {
        return (JVMMethodConstant) JVMMethodConstant.factory.expression_name_frame_ownerType_(_anExpression, _parent.newConstantName(), JVMMethodCompiler.this.newFrame_(_aBlock), JVMMethodCompiler.this.ownerType());
      }
    })));
    this.emit_(_const.asReadInstruction());
    return this;
  }

  public JVMMethodCompiler produceMessageSend_(final MessageNode _messageNode) {
    final st.gravel.core.Symbol _selector;
    if (_parent.allowBlockInlining() && (st.gravel.support.jvm.ArrayExtensions.anySatisfy_(_messageNode.arguments(), new st.gravel.support.jvm.Predicate1<Expression>() {

      @Override
      public boolean value_(final Expression _e) {
        return _e.isBlockNode();
      }
    }) && (!st.gravel.support.jvm.ArrayExtensions.anySatisfy_(_messageNode.arguments(), new st.gravel.support.jvm.Predicate1<Expression>() {

      @Override
      public boolean value_(final Expression _e) {
        return _e.isBlockNode() && _e.allNodesContains_(((st.gravel.support.jvm.Block1<Boolean, Node>) (new st.gravel.support.jvm.Block1<Boolean, Node>() {

          @Override
          public Boolean value_(final Node _n) {
            return (boolean) _n.isSuperNode();
          }
        })));
      }
    })))) {
      return JVMMethodCompiler.this.produceBlockInlineMessageSend_(_messageNode);
    }
    for (final Expression _arg : _messageNode.arguments()) {
      JVMMethodCompiler.this.visit_(_arg);
      JVMMethodCompiler.this.ensureCast_(JVMDynamicObjectType.factory.basicNew());
    }
    _selector = st.gravel.core.Symbol.value(_messageNode.selector());
    this.emit_(DynamicMessageSend.factory.functionName_numArgs_(_parent.selectorConverter().selectorAsFunctionName_(_selector), _selector.numArgs()));
    return this;
  }

  public JVMMethodCompiler produceMethodBody_(final SequenceNode _body) {
    this.visit_(_body);
    Statement[] _temp1 = _body.statements();
    if ((_body.statements().length == 0) || (!_temp1[_temp1.length - 1].isReturnNode())) {
      if (!_stack.isEmpty()) {
        JVMMethodCompiler.this.emit_(Pop.factory.basicNew());
      }
      JVMMethodCompiler.this.produceVarRead_("self");
      JVMMethodCompiler.this.emit_(AReturn.factory.basicNew());
    }
    return this;
  }

  public JVMMethodCompiler produceNonLocalCatchMethod_(final MethodNode _aMethodNode) {
    this.pushLocal_type_(_aMethodNode.nlrMarker(), JVMDefinedObjectType.factory.object());
    this.emit_(NewInstance.factory.type_(JVMDefinedObjectType.factory.object()));
    this.emit_(Dup.factory.basicNew());
    this.emit_(InvokeSpecial.factory.init_voidArguments_(JVMDefinedObjectType.factory.object(), new JVMType[] {}));
    this.localStore_(_aMethodNode.nlrMarker());
    this.try_exception_catch_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        return JVMMethodCompiler.this.produceMethodBody_(_aMethodNode.body());
      }
    }, JVMDefinedObjectType.factory.nonLocalReturn(), new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        final String _ex;
        _ex = JVMMethodCompiler.this.newTempName();
        JVMMethodCompiler.this.pushLocal_type_(_ex, JVMDefinedObjectType.factory.nonLocalReturn());
        JVMMethodCompiler.this.localStore_(_ex);
        JVMMethodCompiler.this.produceVarRead_(_ex);
        JVMMethodCompiler.this.emit_(GetField.factory.ownerType_name_type_(JVMDefinedObjectType.factory.nonLocalReturn(), "marker", JVMDefinedObjectType.factory.object()));
        JVMMethodCompiler.this.produceVarRead_(_aMethodNode.nlrMarker());
        return JVMMethodCompiler.this.emit_(IfObjectsEqualThenElse.factory.trueFrame_falseFrame_(JVMMethodCompiler.this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

          @Override
          public Object value() {
            JVMMethodCompiler.this.produceVarRead_(_ex);
            JVMMethodCompiler.this.emit_(GetField.factory.ownerType_name_type_(JVMDefinedObjectType.factory.nonLocalReturn(), "returnValue", JVMDynamicObjectType.factory.basicNew()));
            return JVMMethodCompiler.this.emit_(AReturn.factory.basicNew());
          }
        }), JVMMethodCompiler.this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

          @Override
          public Object value() {
            JVMMethodCompiler.this.produceVarRead_(_ex);
            return JVMMethodCompiler.this.emit_(AThrow.factory.basicNew());
          }
        })));
      }
    });
    return this;
  }

  public JVMMethodCompiler producePrimitive_def_(final MethodNode _aMethodNode, final String[] _prim) {
    final JVMDefinedObjectType _ownerType;
    final String _name;
    final Invoke _invoke;
    final JVMMethodType[] _staticSignature;
    final int[] _selfOffset;
    _selfOffset = new int[1];
    _staticSignature = new JVMMethodType[1];
    _ownerType = JVMDefinedObjectType.factory.dottedClassName_(_prim[0]);
    _name = _prim[1];
    _invoke = _parent.createInvokeInstruction_name_numArgs_(_ownerType, _name, _aMethodNode.arguments().length);
    if (_invoke == null) {
      JVMMethodCompiler.this.emit_(NewInstance.factory.type_(JVMDefinedObjectType.factory.runtimeException()));
      JVMMethodCompiler.this.emit_(Dup.factory.basicNew());
      JVMMethodCompiler.this.pushString_("Cannot find method " + _ownerType.descriptorString() + ">>" + _name);
      JVMMethodCompiler.this.emit_(InvokeSpecial.factory.init_voidArguments_(JVMDefinedObjectType.factory.runtimeException(), st.gravel.support.jvm.ArrayFactory.with_(JVMDefinedObjectType.factory.string())));
      JVMMethodCompiler.this.emit_(AThrow.factory.basicNew());
      return JVMMethodCompiler.this;
    }
    _staticSignature[0] = _invoke.staticSignature();
    if (_invoke.isInvokeStatic() && st.gravel.support.jvm.IntegerExtensions.equals_(_invoke.signature().numArgs(), _aMethodNode.numArgs())) {
      _selfOffset[0] = 0;
    } else {
      _selfOffset[0] = 1;
      JVMMethodCompiler.this.produceVarRead_("self");
      JVMMethodCompiler.this.ensureCast_(_staticSignature[0].arguments()[0]);
    }
    for (int _temp1 = 0; _temp1 < _aMethodNode.arguments().length; _temp1++) {
      final int _i = _temp1 + 1;
      final VariableDeclarationNode _each = _aMethodNode.arguments()[_temp1];
      JVMMethodCompiler.this.produceVarRead_(_each.name());
      JVMMethodCompiler.this.ensureCast_(_staticSignature[0].arguments()[(_i + (_selfOffset[0])) - 1]);
    }
    this.emit_(_invoke);
    if (_staticSignature[0].returnType().isVoidType()) {
      JVMMethodCompiler.this.produceVarRead_("self");
    } else {
      JVMMethodCompiler.this.ensureCast_(JVMDynamicObjectType.factory.basicNew());
    }
    this.emit_(AReturn.factory.basicNew());
    return this;
  }

  public JVMMethodCompiler produceSafe_to_counterName_step_do_(final String _start, final String _stop, final String _counterName, final int _step, final Node _doSequence) {
    this.emit_(this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        JVMMethodCompiler.this.pushLocal_(_counterName);
        JVMMethodCompiler.this.produceVarRead_(_start);
        JVMMethodCompiler.this.localStore_(_counterName);
        return JVMMethodCompiler.this.emit_(WhileTrueLoop.factory.testFrame_doFrame_(JVMMethodCompiler.this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

          @Override
          public Object value() {
            final String _compareFunctionName;
            JVMMethodCompiler.this.produceVarRead_(_counterName);
            JVMMethodCompiler.this.produceVarRead_(_stop);
            _compareFunctionName = (_step < 0) ? _parent.selectorConverter().selectorAsFunctionName_(st.gravel.core.Symbol.value(">=")) : _parent.selectorConverter().selectorAsFunctionName_(st.gravel.core.Symbol.value("<="));
            JVMMethodCompiler.this.emit_(DynamicMessageSend.factory.functionName_numArgs_(_compareFunctionName, 1));
            return JVMMethodCompiler.this.ensureCast_(JVMBooleanType.factory.basicNew());
          }
        }), JVMMethodCompiler.this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

          @Override
          public Object value() {
            JVMMethodCompiler.this.visit_(_doSequence);
            JVMMethodCompiler.this.trashStack();
            JVMMethodCompiler.this.produceVarRead_(_counterName);
            JVMMethodCompiler.this.pushInt_(_step);
            JVMMethodCompiler.this.ensureCast_(JVMDynamicObjectType.factory.basicNew());
            JVMMethodCompiler.this.emit_(DynamicMessageSend.factory.functionName_numArgs_(_parent.selectorConverter().selectorAsFunctionName_(st.gravel.core.Symbol.value("+")), 1));
            return JVMMethodCompiler.this.localStore_(_counterName);
          }
        })));
      }
    }));
    return this;
  }

  public JVMMethodCompiler produceStatements_(final Statement[] _statements) {
    boolean _temp1 = true;
    for (final Statement _each : _statements) {
      if (_temp1) {
        _temp1 = false;
      } else {
        JVMMethodCompiler.this.emit_(Pop.factory.basicNew());
      }
      JVMMethodCompiler.this.visit_(_each);
    }
    return this;
  }

  public JVMMethodCompiler produceSuperSend_(final MessageNode _messageNode) {
    final st.gravel.core.Symbol _selector;
    final SuperNode _superNode;
    final String _functionName;
    String _superFN;
    _superNode = ((SuperNode) _messageNode.receiver());
    this.produceVarRead_("self");
    for (final Node _arg : _messageNode.arguments()) {
      JVMMethodCompiler.this.visit_(_arg);
    }
    _selector = st.gravel.core.Symbol.value(_messageNode.selector());
    _functionName = _parent.selectorConverter().selectorAsFunctionName_(_selector);
    if (_isBlock) {
      final JVMMethodType _superSig;
      JVMMethodCompiler.this.ensureCast_(_parent.selfType());
      _superFN = "access$" + _functionName;
      _superSig = JVMMethodType.factory.dynamic_(_messageNode.numArgs()).copyWithFirst_(_parent.selfType());
      JVMMethodCompiler.this.emit_(InvokeStatic.factory.ownerType_name_signature_(_parent.ownerType(), _superFN, _superSig));
      _parent.addInvokeSuper_functionName_numArgs_superReference_superSig_(_superFN, _functionName, _selector.numArgs(), _superNode.reference().toString(), _superSig);
    } else {
      JVMMethodCompiler.this.emit_(DynamicSuperSend.factory.functionName_numArgs_superReference_(_functionName, _selector.numArgs(), _superNode.reference().toString()));
    }
    return this;
  }

  public JVMMethodCompiler produceToDoNodeConstantStep_step_(final ToDoNode _toDoNode, final int _step) {
    this.emit_(this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        final String _stop;
        final String _startObj;
        final String _stopObj;
        _startObj = JVMMethodCompiler.this.newTempName();
        _stopObj = JVMMethodCompiler.this.newTempName();
        JVMMethodCompiler.this.pushLocal_(_startObj);
        JVMMethodCompiler.this.pushLocal_(_stopObj);
        JVMMethodCompiler.this.visit_(_toDoNode.start());
        JVMMethodCompiler.this.localStore_(_startObj);
        JVMMethodCompiler.this.visit_(_toDoNode.stop());
        JVMMethodCompiler.this.localStore_(_stopObj);
        JVMMethodCompiler.this.pushLocal_type_(_toDoNode.counterName(), JVMIntType.factory.basicNew());
        _stop = JVMMethodCompiler.this.newTempName();
        JVMMethodCompiler.this.pushLocal_type_(_stop, JVMIntType.factory.basicNew());
        return JVMMethodCompiler.this.try_do_exception_catch_(new st.gravel.support.jvm.Block0<Object>() {

          @Override
          public Object value() {
            JVMMethodCompiler.this.produceVarRead_(_stopObj);
            JVMMethodCompiler.this.produceVarRead_(_startObj);
            JVMMethodCompiler.this.localStore_(_toDoNode.counterName());
            return JVMMethodCompiler.this.localStore_(_stop);
          }
        }, new st.gravel.support.jvm.Block0<Object>() {

          @Override
          public Object value() {
            final Frame _testFrame;
            final Frame _doFrame;
            _testFrame = JVMMethodCompiler.this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

              @Override
              public Object value() {
                JVMMethodCompiler.this.produceVarRead_(_toDoNode.counterName());
                return JVMMethodCompiler.this.produceVarRead_(_stop);
              }
            });
            _doFrame = JVMMethodCompiler.this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

              @Override
              public Object value() {
                JVMMethodCompiler.this.visit_(_toDoNode.doSequence());
                JVMMethodCompiler.this.trashStack();
                return JVMMethodCompiler.this.emit_(IncrementLocal.factory.local_increment_(_locals.get(_toDoNode.counterName()), _step));
              }
            });
            return JVMMethodCompiler.this.emit_((_step > 0) ? WhileLessThanLoop.factory.testFrame_doFrame_(_testFrame, _doFrame) : WhileGreaterThanLoop.factory.testFrame_doFrame_(_testFrame, _doFrame));
          }
        }, JVMDefinedObjectType.factory.classCastException(), new st.gravel.support.jvm.Block0<Object>() {

          @Override
          public Object value() {
            JVMMethodCompiler.this.emit_(Pop.factory.basicNew());
            JVMMethodCompiler.this.renameLocal_to_(_toDoNode.counterName(), JVMMethodCompiler.this.newTempName());
            return JVMMethodCompiler.this.produceSafe_to_counterName_step_do_(_startObj, _stopObj, _toDoNode.counterName(), _step, _toDoNode.doSequence());
          }
        });
      }
    }));
    this.pushNull();
    return this;
  }

  public JVMMethodCompiler produceToDoNodeDynamicStep_(final ToDoNode _toDoNode) {
    st.gravel.support.jvm.ObjectExtensions.halt(this);
    return this;
  }

  public JVMMethodCompiler produceVarRead_(final String _aString) {
    final JVMLocalDeclaration _local;
    final JVMField _cv;
    JVMLocalDeclaration _temp1 = _locals.get(_aString);
    _local = ((JVMLocalDeclaration) _temp1);
    if (_local != null) {
      return JVMMethodCompiler.this.emit_(Load.factory.local_(_local));
    }
    _cv = _copiedVariables.get(_aString);
    this.produceVarRead_(_copiedVariablesOwner);
    this.emit_(_cv.asGetField());
    return this;
  }

  public JVMMethodCompiler pushBoolean_(final boolean _aBoolean) {
    this.emit_(_aBoolean ? PushTrue.factory.basicNew() : PushFalse.factory.basicNew());
    return this;
  }

  public JVMMethodCompiler pushByteArray_(final byte[] _ba) {
    this.pushInt_(_ba.length);
    this.emit_(NewArray.factory.elementType_(JVMByteType.factory.basicNew()));
    for (int _temp1 = 0; _temp1 < _ba.length; _temp1++) {
      final int _i = _temp1 + 1;
      final int _byte = _ba[_temp1];
      JVMMethodCompiler.this.emit_(Dup.factory.basicNew());
      JVMMethodCompiler.this.pushInt_((_i - 1));
      JVMMethodCompiler.this.pushInt_(_byte);
      JVMMethodCompiler.this.emit_(ByteArrayStore.factory.basicNew());
    }
    return this;
  }

  public JVMMethodCompiler pushChar_(final Object _anObject) {
    return this.emit_(PushChar.factory.value_(((char) _anObject)));
  }

  public JVMMethodCompiler pushDouble_(final double _aDouble) {
    this.emit_(PushDouble.factory.value_(_aDouble));
    return this;
  }

  public JVMMethodCompiler pushFloat_(final float _aFloat) {
    this.emit_(PushFloat.factory.value_(_aFloat));
    return this;
  }

  public JVMMethodCompiler pushInt_(final int _anInteger) {
    this.emit_(PushInt.factory.value_(_anInteger));
    return this;
  }

  public JVMMethodCompiler pushLargeInteger_(final java.math.BigInteger _anInteger) {
    this.emit_(NewInstance.factory.type_(JVMDefinedObjectType.factory.bigInteger()));
    this.emit_(Dup.factory.basicNew());
    this.pushString_(_anInteger.toString());
    this.emit_(InvokeSpecial.factory.init_voidArguments_(JVMDefinedObjectType.factory.bigInteger(), st.gravel.support.jvm.ArrayFactory.with_(JVMDefinedObjectType.factory.string())));
    return this;
  }

  public JVMMethodCompiler pushLocal_(final String _varName) {
    this.pushLocal_type_(_varName, JVMDynamicObjectType.factory.basicNew());
    return this;
  }

  public JVMMethodCompiler pushLocal_type_(final String _varName, final JVMType _aJVMType) {
    if (_locals.containsKey(_varName)) {
      throw new RuntimeException("Local already declared");
    }
    _locals.put(_varName, JVMLocalDeclaration.factory.varName_type_index_(_varName, _aJVMType, _locals.size()));
    return this;
  }

  public JVMMethodCompiler pushNull() {
    return this.emit_(PushNull.factory.basicNew());
  }

  public JVMMethodCompiler pushString_(final Object _anObject) {
    return this.emit_(PushString.factory.value_(((String) _anObject)));
  }

  public JVMMethodCompiler pushSymbol_(final st.gravel.core.Symbol _aSymbol) {
    this.pushString_(_aSymbol.asString());
    this.emit_(InvokeStatic.factory.ownerType_name_signature_(JVMDefinedObjectType.factory.symbol(), "value", JVMDefinedObjectType.factory.symbol().withArgument_(JVMDefinedObjectType.factory.string())));
    return this;
  }

  public JVMMethodCompiler renameLocal_to_(final String _oldName, final String _newName) {
    final JVMLocalDeclaration _local;
    _local = _locals.remove(_oldName);
    _locals.put(_newName, _local.withVarName_(_newName));
    return this;
  }

  public JVMMethodCompiler reset() {
    _locals = new java.util.HashMap<String, JVMLocalDeclaration>();
    _stack = JVMStack.factory.basicNew();
    _instructions = new java.util.ArrayList();
    return this;
  }

  public JVMMethodCompiler trashStack() {
    boolean _temp1 = false;
    while (!_temp1) {
      _temp1 = _stack.isEmpty();
      if (!_temp1) {
        JVMMethodCompiler.this.emit_(Pop.factory.basicNew());
      }
    }
    return this;
  }

  public JVMMethodCompiler try_do_exception_catch_(final st.gravel.support.jvm.Block0<Object> _tryBlock, final st.gravel.support.jvm.Block0<Object> _doBlock, final JVMDefinedObjectType _ex, final st.gravel.support.jvm.Block0<Object> _catchBlock) {
    this.emit_(TryCatch.factory.tryFrame_doFrame_exception_catchFrame_(this.newFrame_(_tryBlock), this.newFrame_(_doBlock), _ex, this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        _stack.push_(_ex);
        return _catchBlock.value();
      }
    })));
    return this;
  }

  public JVMMethodCompiler try_exception_catch_(final st.gravel.support.jvm.Block0<Object> _tryBlock, final JVMDefinedObjectType _ex, final st.gravel.support.jvm.Block0<Object> _catchBlock) {
    this.emit_(TryCatch.factory.tryFrame_doFrame_exception_catchFrame_(this.newFrame_(_tryBlock), null, _ex, this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        _stack.push_(_ex);
        return _catchBlock.value();
      }
    })));
    return this;
  }

  @Override
  public JVMMethodCompiler visitArrayAtNode_(final ArrayAtNode _node) {
    this.visit_(_node.receiver());
    this.ensureCast_(JVMArrayType.factory.elementType_(JVMDynamicObjectType.factory.basicNew()));
    this.visit_(_node.index());
    this.ensureCast_(JVMIntType.factory.basicNew());
    this.pushInt_(1);
    this.emit_(Subtract.factory.basicNew());
    this.emit_(ObjectArrayLoad.factory.basicNew());
    return this;
  }

  @Override
  public JVMMethodCompiler visitArrayAtPutNode_(final ArrayAtPutNode _node) {
    this.visit_(_node.receiver());
    this.ensureCast_(JVMArrayType.factory.elementType_(JVMDynamicObjectType.factory.basicNew()));
    this.visit_(_node.index());
    this.ensureCast_(JVMIntType.factory.basicNew());
    this.pushInt_(1);
    this.emit_(Subtract.factory.basicNew());
    this.visit_(_node.value());
    this.emit_(DupX2.factory.basicNew());
    this.emit_(ObjectArrayStore.factory.basicNew());
    return this;
  }

  @Override
  public JVMMethodCompiler visitArrayLiteralNode_(final ArrayLiteralNode _literalNode) {
    this.produceConstant_ifAbsentPut_(_literalNode, new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        JVMMethodCompiler.this.pushInt_(_literalNode.elements().length);
        JVMMethodCompiler.this.emit_(NewArray.factory.elementType_(JVMDynamicObjectType.factory.basicNew()));
        for (int _temp1 = 0; _temp1 < _literalNode.elements().length; _temp1++) {
          final int _i = _temp1 + 1;
          final Node _elem = _literalNode.elements()[_temp1];
          JVMMethodCompiler.this.emit_(Dup.factory.basicNew());
          JVMMethodCompiler.this.pushInt_((_i - 1));
          JVMMethodCompiler.this.visit_(_elem);
          JVMMethodCompiler.this.ensureCast_(JVMDynamicObjectType.factory.basicNew());
          JVMMethodCompiler.this.emit_(ObjectArrayStore.factory.basicNew());
        }
        return JVMMethodCompiler.this;
      }
    });
    return this;
  }

  @Override
  public JVMMethodCompiler visitArraySizeNode_(final ArraySizeNode _node) {
    this.visit_(_node.receiver());
    this.ensureCast_(JVMArrayType.factory.elementType_(JVMDynamicObjectType.factory.basicNew()));
    this.emit_(ArrayLength.factory.basicNew());
    return this;
  }

  @Override
  public JVMMethodCompiler visitBlockNode_(final BlockNode _blockNode) {
    final JVMVariable[] _nCopiedVariables;
    final BlockInnerClass[] _innerClassDefinition;
    _innerClassDefinition = new BlockInnerClass[1];
    _nCopiedVariables = this.copiedVariablesForBlockNode_(_blockNode);
    _innerClassDefinition[0] = this.createBlockInnerClass_copiedVariables_(_blockNode, _nCopiedVariables);
    if (_nCopiedVariables.length == 0) {
      JVMMethodCompiler.this.produceConstant_ifAbsentPut_(_blockNode, new st.gravel.support.jvm.Block0<Object>() {

        @Override
        public Object value() {
          JVMMethodCompiler.this.emit_(NewInstance.factory.type_(_innerClassDefinition[0].ownerType()));
          JVMMethodCompiler.this.emit_(Dup.factory.basicNew());
          return JVMMethodCompiler.this.emit_(InvokeSpecial.factory.init_voidArguments_(_innerClassDefinition[0].ownerType(), new JVMType[] {}));
        }
      });
    } else {
      JVMMethodCompiler.this.emit_(NewInstance.factory.type_(_innerClassDefinition[0].ownerType()));
      JVMMethodCompiler.this.emit_(Dup.factory.basicNew());
      for (final JVMVariable _each : _nCopiedVariables) {
        JVMMethodCompiler.this.produceVarRead_(_each.varName());
        JVMMethodCompiler.this.ensureCast_(_each.type());
      }
      JVMMethodCompiler.this.emit_(InvokeSpecial.factory.init_voidArguments_(_innerClassDefinition[0].ownerType(), st.gravel.support.jvm.ArrayExtensions.collect_(_nCopiedVariables, ((st.gravel.support.jvm.Block1<JVMType, JVMVariable>) (new st.gravel.support.jvm.Block1<JVMType, JVMVariable>() {

        @Override
        public JVMType value_(final JVMVariable _each) {
          return (JVMType) _each.type();
        }
      })))));
    }
    return this;
  }

  @Override
  public JVMMethodCompiler visitBooleanAndNode_(final BooleanAndNode _aNode) {
    this.emit_(AndThenElse.factory.left_right_(this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        JVMMethodCompiler.this.visit_(_aNode.left());
        return JVMMethodCompiler.this.ensureCast_(JVMBooleanType.factory.basicNew());
      }
    }), this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        JVMMethodCompiler.this.visit_(_aNode.right());
        return JVMMethodCompiler.this.ensureCast_(JVMBooleanType.factory.basicNew());
      }
    })));
    return this;
  }

  @Override
  public JVMMethodCompiler visitBooleanLiteralNode_(final BooleanLiteralNode _literalNode) {
    this.pushBoolean_(_literalNode.value());
    return this;
  }

  @Override
  public JVMMethodCompiler visitBooleanOrNode_(final BooleanOrNode _aNode) {
    this.emit_(OrThenElse.factory.left_right_(this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        JVMMethodCompiler.this.visit_(_aNode.left());
        return JVMMethodCompiler.this.ensureCast_(JVMBooleanType.factory.basicNew());
      }
    }), this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        JVMMethodCompiler.this.visit_(_aNode.right());
        return JVMMethodCompiler.this.ensureCast_(JVMBooleanType.factory.basicNew());
      }
    })));
    return this;
  }

  @Override
  public JVMMethodCompiler visitByteArrayLiteralNode_(final ByteArrayLiteralNode _anObject) {
    this.produceConstant_ifAbsentPut_(_anObject, new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        return JVMMethodCompiler.this.pushByteArray_(_anObject.value());
      }
    });
    return this;
  }

  @Override
  public JVMMethodCompiler visitCascadeNode_(final CascadeNode _cascadeNode) {
    this.visit_(_cascadeNode.receiver());
    for (final MessageNode _message : st.gravel.support.jvm.ArrayExtensions.copyWithoutLast(_cascadeNode.messages())) {
      JVMMethodCompiler.this.emit_(Dup.factory.basicNew());
      JVMMethodCompiler.this.produceMessageSend_(_message);
      JVMMethodCompiler.this.emit_(Pop.factory.basicNew());
    }
    MessageNode[] _temp1 = _cascadeNode.messages();
    this.produceMessageSend_(_temp1[_temp1.length - 1]);
    return this;
  }

  @Override
  public JVMMethodCompiler visitCharacterLiteralNode_(final CharacterLiteralNode _literalNode) {
    this.pushChar_(_literalNode.value());
    return this;
  }

  @Override
  public JVMMethodCompiler visitCreateHolderNode_(final CreateHolderNode _aNode) {
    this.pushInt_(1);
    this.emit_(NewArray.factory.elementType_(JVMDynamicObjectType.factory.basicNew()));
    return this;
  }

  @Override
  public JVMMethodCompiler visitDoubleLiteralNode_(final DoubleLiteralNode _anObject) {
    this.pushDouble_(((double) _anObject.value()));
    return this;
  }

  @Override
  public JVMMethodCompiler visitFieldReadNode_(final FieldReadNode _aNode) {
    this.visit_(_aNode.owner());
    this.emit_(DynamicFieldRead.factory.name_type_(_aNode.name(), TypeNodeToJVMTypeConverter.factory.namespace_(_parent.namespace()).visit_(_aNode.type())));
    return this;
  }

  @Override
  public JVMMethodCompiler visitFieldWriteNode_(final FieldWriteNode _aNode) {
    final JVMType _fieldType;
    this.visit_(_aNode.owner());
    this.visit_(_aNode.value());
    _fieldType = TypeNodeToJVMTypeConverter.factory.namespace_(_parent.namespace()).visit_(_aNode.type());
    this.ensureCast_(_fieldType);
    this.emit_(DupX1.factory.basicNew());
    this.emit_(DynamicFieldWrite.factory.name_type_(_aNode.name(), _fieldType));
    return this;
  }

  @Override
  public JVMMethodCompiler visitFixedPointLiteralNode_(final FixedPointLiteralNode _anObject) {
    this.pushLargeInteger_(_anObject.numerator());
    this.emit_(DynamicMessageSend.factory.functionName_numArgs_(_parent.selectorConverter().selectorAsFunctionName_(st.gravel.core.Symbol.value("compressed")), 0));
    this.pushLargeInteger_(_anObject.denominator());
    this.emit_(DynamicMessageSend.factory.functionName_numArgs_(_parent.selectorConverter().selectorAsFunctionName_(st.gravel.core.Symbol.value("compressed")), 0));
    this.emit_(DynamicMessageSend.factory.functionName_numArgs_(_parent.selectorConverter().selectorAsFunctionName_(st.gravel.core.Symbol.value("/")), 1));
    this.pushInt_(_anObject.scale());
    this.ensureCast_(JVMDynamicObjectType.factory.basicNew());
    this.emit_(DynamicMessageSend.factory.functionName_numArgs_(_parent.selectorConverter().selectorAsFunctionName_(st.gravel.core.Symbol.value("asScaledDecimal:")), 1));
    return this;
  }

  @Override
  public JVMMethodCompiler visitFloatLiteralNode_(final FloatLiteralNode _anObject) {
    this.pushFloat_(((float) _anObject.value()));
    return this;
  }

  @Override
  public JVMMethodCompiler visitGlobalReadNode_(final GlobalReadNode _aNode) {
    this.emit_(DynamicGlobalRead.factory.namespace_name_(_aNode.namespace().toString(), _aNode.name()));
    return this;
  }

  @Override
  public JVMMethodCompiler visitGlobalWriteNode_(final GlobalWriteNode _aNode) {
    this.visit_(_aNode.value());
    this.ensureCast_(JVMDynamicObjectType.factory.basicNew());
    this.emit_(DynamicGlobalWrite.factory.namespace_name_(_aNode.namespace().toString(), _aNode.name()));
    return this;
  }

  @Override
  public JVMMethodCompiler visitHolderDeclarationNode_(final HolderDeclarationNode _aNode) {
    this.pushLocal_type_(_aNode.name(), JVMArrayType.factory.elementType_(JVMDynamicObjectType.factory.basicNew()));
    return this;
  }

  @Override
  public JVMMethodCompiler visitIdentityComparisonNode_(final IdentityComparisonNode _aNode) {
    this.visit_(BinaryMessageNode.factory.receiver_selector_argument_(_aNode.left(), "==", _aNode.right()));
    return this;
  }

  @Override
  public JVMMethodCompiler visitIfTrueIfFalseNode_(final IfTrueIfFalseNode _aNode) {
    this.visit_(_aNode.test());
    this.emit_(IfThenElse.factory.trueFrame_falseFrame_(this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        return JVMMethodCompiler.this.visit_(_aNode.trueSequence());
      }
    }), this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        return JVMMethodCompiler.this.visit_(_aNode.falseSequence());
      }
    })));
    return this;
  }

  @Override
  public JVMMethodCompiler visitInlineExpressionCollection_(final InlineExpressionCollection _aNode) {
    this.produceStatements_(_aNode.expressions());
    return this;
  }

  @Override
  public JVMMethodCompiler visitInstanceCreationNode_(final InstanceCreationNode _node) {
    this.emit_(DynamicCreateInstance.factory.reference_(_node.reference().toString()));
    return this;
  }

  @Override
  public JVMMethodCompiler visitIntegerLiteralNode_(final IntegerLiteralNode _anObject) {
    final Object[] _value;
    _value = new Object[1];
    _value[0] = _anObject.value();
    if (_value[0] instanceof Integer) {
      return JVMMethodCompiler.this.pushInt_(((int) (_value[0])));
    }
    st.gravel.support.jvm.ObjectExtensions.assert_(this, _value[0] instanceof java.math.BigInteger);
    this.produceConstant_ifAbsentPut_(_anObject, new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        return JVMMethodCompiler.this.pushLargeInteger_(((java.math.BigInteger) (_value[0])));
      }
    });
    return this;
  }

  @Override
  public JVMMethodCompiler visitIsNilNode_(final IsNilNode _aNode) {
    this.visit_(_aNode.receiver());
    st.gravel.support.jvm.ObjectExtensions.assert_(this, _stack.peek().isDynamicObjectType());
    this.emit_(IfObjectIsNullThenElse.factory.r_boolean());
    return this;
  }

  @Override
  public JVMMethodCompiler visitLocalReadNode_(final LocalReadNode _localReadNode) {
    this.produceVarRead_(_localReadNode.name());
    return this;
  }

  @Override
  public JVMMethodCompiler visitLocalWriteNode_(final LocalWriteNode _localWriteNode) {
    this.visit_(_localWriteNode.value());
    this.emit_(Dup.factory.basicNew());
    this.localStore_(_localWriteNode.name());
    return this;
  }

  @Override
  public JVMMethodCompiler visitMessageNode_(final MessageNode _messageNode) {
    if (_messageNode.receiver().isSuperNode()) {
      return JVMMethodCompiler.this.produceSuperSend_(_messageNode);
    }
    this.visit_(_messageNode.receiver());
    this.ensureCast_(JVMDynamicObjectType.factory.basicNew());
    this.produceMessageSend_(_messageNode);
    return this;
  }

  @Override
  public JVMMethodCompiler visitMethodNode_(final MethodNode _aMethodNode) {
    final String[] _prim;
    final JVMType[] _argumentTypes;
    this.reset();
    _methodName = _parent.selectorConverter().selectorAsFunctionName_(st.gravel.core.Symbol.value(_aMethodNode.selector()));
    _argumentTypes = st.gravel.support.jvm.ArrayExtensions.collect_(_aMethodNode.arguments(), new st.gravel.support.jvm.Block1<JVMType, VariableDeclarationNode>() {

      @Override
      public JVMType value_(final VariableDeclarationNode _arg) {
        if (_arg.isHolderDeclarationNode()) {
          return JVMArrayType.factory.elementType_(JVMDynamicObjectType.factory.basicNew());
        } else {
          return JVMDynamicObjectType.factory.basicNew();
        }
      }
    });
    _signature = JVMMethodType.factory.returnType_arguments_(JVMDynamicObjectType.factory.basicNew(), _argumentTypes);
    if (_isStatic) {
      _signature = _signature.copyWithFirst_(JVMDynamicObjectType.factory.basicNew());
    }
    this.pushLocal_("self");
    st.gravel.support.jvm.ArrayExtensions.with_do_(_aMethodNode.arguments(), _argumentTypes, new st.gravel.support.jvm.Block2<Object, VariableDeclarationNode, JVMType>() {

      @Override
      public Object value_value_(final VariableDeclarationNode _each, final JVMType _type) {
        return JVMMethodCompiler.this.pushLocal_type_(_each.name(), _type);
      }
    });
    _prim = _aMethodNode.primitiveIn_(_parent.selfType().dottedClassName());
    if (_prim != null) {
      return JVMMethodCompiler.this.producePrimitive_def_(_aMethodNode, _prim);
    }
    if (_aMethodNode.nlrMarker() == null) {
      JVMMethodCompiler.this.produceMethodBody_(_aMethodNode.body());
    } else {
      JVMMethodCompiler.this.produceNonLocalCatchMethod_(_aMethodNode);
    }
    return this;
  }

  @Override
  public JVMMethodCompiler visitNamespacedVariableNode_(final NamespacedVariableNode _aNode) {
    this.emit_(DynamicGlobalRead.factory.namespace_name_(_aNode.reference().toString(), _aNode.name()));
    return this;
  }

  @Override
  public JVMMethodCompiler visitNilLiteralNode_(final NilLiteralNode _literalNode) {
    this.pushNull();
    return this;
  }

  @Override
  public JVMMethodCompiler visitNonLocalReturnNode_(final NonLocalReturnNode _returnNode) {
    this.emit_(NewInstance.factory.type_(JVMDefinedObjectType.factory.nonLocalReturn()));
    this.emit_(Dup.factory.basicNew());
    this.visit_(_returnNode.value());
    this.ensureCast_(JVMDynamicObjectType.factory.basicNew());
    this.produceVarRead_(_returnNode.marker());
    this.emit_(InvokeSpecial.factory.init_voidArguments_(JVMDefinedObjectType.factory.nonLocalReturn(), st.gravel.support.jvm.ArrayFactory.with_with_(JVMDynamicObjectType.factory.basicNew(), JVMDefinedObjectType.factory.object())));
    this.emit_(AThrow.factory.basicNew());
    return this;
  }

  @Override
  public JVMMethodCompiler visitReadHolderNode_(final ReadHolderNode _readHolderNode) {
    this.produceVarRead_(_readHolderNode.varName());
    this.pushInt_(0);
    this.emit_(ObjectArrayLoad.factory.basicNew());
    return this;
  }

  @Override
  public JVMMethodCompiler visitReferenceLiteralNode_(final ReferenceLiteralNode _anObject) {
    this.pushNull();
    return this;
  }

  @Override
  public JVMMethodCompiler visitReturnNode_(final ReturnNode _anObject) {
    this.visit_(_anObject.value());
    this.ensureCast_(JVMDynamicObjectType.factory.basicNew());
    this.emit_(AReturn.factory.basicNew());
    return this;
  }

  @Override
  public JVMMethodCompiler visitSelfNode_(final SelfNode _anObject) {
    this.produceVarRead_("self");
    return this;
  }

  @Override
  public JVMMethodCompiler visitSequenceNode_(final SequenceNode _anObject) {
    for (final VariableDeclarationNode _each : _anObject.temporaries()) {
      JVMMethodCompiler.this.visit_(_each);
    }
    this.produceStatements_(_anObject.statements());
    return this;
  }

  @Override
  public JVMMethodCompiler visitStringLiteralNode_(final StringLiteralNode _literalNode) {
    this.pushString_(_literalNode.value());
    return this;
  }

  @Override
  public JVMMethodCompiler visitSymbolLiteralNode_(final SymbolLiteralNode _literalNode) {
    this.produceConstant_ifAbsentPut_(_literalNode, new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        return JVMMethodCompiler.this.pushSymbol_(_literalNode.value());
      }
    });
    return this;
  }

  @Override
  public JVMMethodCompiler visitToDoNode_(final ToDoNode _toDoNode) {
    if (_toDoNode.step().isIntegerLiteralNode()) {
      final Object _step;
      _step = ((IntegerLiteralNode) _toDoNode.step()).value();
      JVMMethodCompiler.this.produceToDoNodeConstantStep_step_(_toDoNode, ((int) _step));
    } else {
      JVMMethodCompiler.this.produceToDoNodeDynamicStep_(_toDoNode);
    }
    return this;
  }

  @Override
  public JVMMethodCompiler visitTypeCast_(final TypeCast _aTypeCast) {
    this.visit_(_aTypeCast.expression());
    return this;
  }

  @Override
  public JVMMethodCompiler visitVariableDeclarationNode_(final VariableDeclarationNode _aNode) {
    this.pushLocal_type_(_aNode.name(), JVMDynamicObjectType.factory.basicNew());
    this.pushNull();
    this.localStore_(_aNode.name());
    return this;
  }

  @Override
  public JVMMethodCompiler visitWhileFalseNode_(final WhileFalseNode _aNode) {
    this.emit_(WhileFalseLoop.factory.testFrame_doFrame_(this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        JVMMethodCompiler.this.visit_(_aNode.testSequence());
        return JVMMethodCompiler.this.ensureCast_(JVMBooleanType.factory.basicNew());
      }
    }), this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        if (_aNode.doSequence() != null) {
          JVMMethodCompiler.this.visit_(_aNode.doSequence());
          return JVMMethodCompiler.this.trashStack();
        }
        return JVMMethodCompiler.this;
      }
    })));
    this.pushNull();
    return this;
  }

  @Override
  public JVMMethodCompiler visitWhileTrueNode_(final WhileTrueNode _aNode) {
    this.emit_(WhileTrueLoop.factory.testFrame_doFrame_(this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        JVMMethodCompiler.this.visit_(_aNode.testSequence());
        return JVMMethodCompiler.this.ensureCast_(JVMBooleanType.factory.basicNew());
      }
    }), this.newFrame_(new st.gravel.support.jvm.Block0<Object>() {

      @Override
      public Object value() {
        if (_aNode.doSequence() != null) {
          JVMMethodCompiler.this.visit_(_aNode.doSequence());
          return JVMMethodCompiler.this.trashStack();
        }
        return JVMMethodCompiler.this;
      }
    })));
    this.pushNull();
    return this;
  }

  @Override
  public JVMMethodCompiler visitWriteHolderNode_(final WriteHolderNode _writeHolderNode) {
    this.produceVarRead_(_writeHolderNode.varName());
    this.pushInt_(0);
    this.visit_(_writeHolderNode.value());
    this.ensureCast_(JVMDynamicObjectType.factory.basicNew());
    this.emit_(DupX2.factory.basicNew());
    this.emit_(ObjectArrayStore.factory.basicNew());
    return this;
  }

  @Override
  public JVMMethodCompiler visit_(final Node _node) {
    if ((_node.sourcePosition() != null) && (_instructions != null)) {
      final Integer _lineNumber;
      _lineNumber = JVMMethodCompiler.this.lineNumberOf_(_node.sourcePosition());
      if (_lineNumber != null) {
        JVMMethodCompiler.this.emit_(LabelLineNumber.factory.line_(_lineNumber));
      }
    }
    super.visit_(_node);
    return this;
  }
}
TOP

Related Classes of st.gravel.support.compiler.jvm.JVMMethodCompiler$JVMMethodCompiler_Factory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.