package rebelsky.pal;

/**
 * A label in a PAL program.  The address associated with a label
 * gets assigned by the computer.
 *
 * @author Samuel A. Rebelsky
 * @version 1.1 of December 2002
 */
public class Label
  extends Variable
  implements Instruction
{
  // +---------------+-----------------------------------------------------
  // | Static Fields |
  // +---------------+

  /** The counter of temporary labels (so that not all labels need names). */
  static int labels = 0;


  // +--------+------------------------------------------------------------
  // | Fields |
  // +--------+

  /** The string used to name the label. */
  String name;

  /** The corresponding address.  Set to -1 for "unset". */
  int address = -1;


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

  /**
   * Build a new label with a specified name.
   */
  public Label(String name) {
    this.name = name + "_" + labels++;
  } // Label(String)

  /**
   * Build a new label without a specified name.
   */
  public Label() {
    this.name = "_L_" + labels++;
  } // Label()


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

  /** 
   * Execute the instruction on a machine. 
   * 
   * @exception Exception
   *   If the instruction fails to execute.
   */
  public void execute(Computer hal)
    throws Exception
  {
    // Labels do nothing.
  } // execute(Computer)

  /** 
   * Get the integer stored in this location. 
   *
   * @exception Exception
   *   If the label does not yet have an address.
   */
  public int iget(Computer hal)
    throws Exception
  {
    if (this.address == -1)
      throw new Exception("Attempt to use a label with no address.");
    return this.address;
  } // iget()

  /**
   * Set the address associated with this label.
   *
   * @exception Exception
   *   Always.  You're not allowed to change labels.
   */
  public void iset(Computer hal, int newval)
    throws Exception
  {
    throw new Exception("Attempt to change a label's address.");
  } // iset(int)

  /** Convert the instruction to a string (usually for printing). */
  public String toString() {
    if (this.address == -1) 
      return this.name;
    else
      return this.name + "[" + this.address + "]";
  } // toString()

} // class Label

