//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// PLEASE DO NOT EDIT WITHOUT THE EXPLICIT CONSENT OF THE AUTHOR! \\
//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\

package ilog.language.design.base;

/**
 * @version     Last modified on Fri Feb 22 20:26:10 2002 by hak
 * @author      <a href="mailto:hak@ilog.fr">Hassan A&iuml;t-Kaci</a>
 * @copyright   &copy; 2000-2002 <a href="http://www.ilog.fr/">ILOG, S.A.</a>
 */

import ilog.language.design.backend.Runtime;
import ilog.language.design.backend.RuntimeTuple;

public class PushTuple extends Instruction implements PushValue, PushObject
{
  private int _intDim;
  private int _realDim;
  private int _objectDim;

  public PushTuple (int intDim, int realDim, int objectDim)
    {
      setName("PUSH_TUPLE");
      _intDim = intDim;
      _realDim = realDim;
      _objectDim = objectDim;
    }

  final int intDimension ()
    {
      return _intDim;
    }
  
  final int realDimension ()
    {
      return _realDim;
    }
  
  final int objectDimension ()
    {
      return _objectDim;
    }
  
  public final void execute (Runtime r)
    {
      if (_intDim+_realDim+_objectDim == 0)
        r.pushObject(RuntimeTuple.EMPTY);
      else
        {
          int[] intComponents = (_intDim == 0 ? null : new int[_intDim]);
          double[] realComponents = (_realDim == 0 ? null : new double[_realDim]);
          Object[] objectComponents = (_objectDim == 0 ? null : new Object[_objectDim]);

          for (int i=0; i<_intDim; i++) intComponents[i] = r.popInt();
          for (int i=0; i<_realDim; i++) realComponents[i] = r.popReal();
          for (int i=0; i<_objectDim; i++) objectComponents[i] = r.popObject();

          r.pushObject(new RuntimeTuple(intComponents,realComponents,objectComponents));
        }
      r.incIP();
    }

  public final boolean equals (Object object)
    {
      if (this == object)
        return true;

      if (!(object instanceof PushTuple))
        return false;

      PushTuple PushTuple = (PushTuple)object;

      return _intDim    == PushTuple.intDimension()
          && _realDim   == PushTuple.realDimension()
          && _objectDim == PushTuple.objectDimension();
    }

  public final int hashCode ()
    {
      return name().hashCode() + 2*_intDim + 3*_realDim + 5*_objectDim;
    }

  public final String toString ()
    {
      return name() + "(" + _intDim + "," + _realDim + "," + _objectDim + ")";
    }
}
