package rebelsky.pal;

/**
 * Memory locations for PAL, the pseudo-assembly language.  These 
 * locations are fairly general: they can be indexed by any kind
 * of container (and not just constants, registers, or temporaries).
 * However, to ease translation to real assembly language, they
 * really should be indexed only by constants or registers.
 *
 * @author Samuel A. Rebelsky
 * @version 1.2 of May 2004
 */
public class MemLoc
  extends Variable
{
  // +--------+------------------------------------------------------------
  // | Fields |
  // +--------+

  /** The index of the memory location. */
  Variable index;


  // +--------------+------------------------------------------------------
  // | Constructors |
  // +--------------+

  /** Create a new memory location indexed by the specified container. */
  public MemLoc(Variable index) {
    this.index = index;
  } // MemLoc(Variable)


  // +---------+-----------------------------------------------------------
  // | Methods |
  // +---------+

  /** 
   * Get the integer stored in this memory location.
   *
   * @exception Exception
   *   If the location is invalid.
   */
  public int iget(Computer hal)
    throws Exception
  {
    int pos = index.iget(hal);
    if ((pos < 0) || (pos > hal.memory.length))
      throw new Exception("Invalid memory location: " + pos);
    return hal.memory[pos];
  } // iget(Computer)

  /**
   * Store an integer in this memory location.
   *
   * @exception Exception
   *   If the index is invalid.
   */
  public void iset(Computer hal, int newval)
    throws Exception
  {
    int pos = index.iget(hal);
    if ((pos < 0) || (pos > hal.memory.length))
      throw new Exception("Invalid memory location: " + pos);
    hal.memory[pos] = newval;
  } // iset(Computer,int)

  /**
   * Get the address (as another variable).
   */
  public Variable dereference()
  {
    return this.index;
  } // dereference()

  /**
   * Convert to a string (e.g., for printing).
   */
  public String toString() {
    return "MEM[" + index.toString() + "]";
  } // toString()

} // class MemLoc

