/**
  * Consume the first work on the input tape
  *
  * @return The word of input
  * @throws EmptyInputException
  */
 public StackValue<?> consumeInput() throws EmptyInputException {
   if (hasInput()) {
     StackValue<?> value = input.get(inputIndex++);
     for (StackMachineListener l : listeners) l.inputConsumed(inputIndex);
     return value;
   } else throw new EmptyInputException(programCounter);
 }
 /** Resets the stack machine to the state it was in before it started running the stack program */
 public void reset() {
   this.programCounter = 0;
   this.stack.clear();
   this.numInstructions = 0;
   this.store = new StackValue<?>[STORE_SIZE];
   this.inputIndex = 0;
   this.output = new ArrayList<StackValue<?>>();
   for (int i = 0; i < STORE_SIZE; i++) {
     store[i] = new IntStackValue(0);
     for (StackMachineListener l : listeners) l.storeChanged(i);
   }
   for (StackMachineListener l : listeners) l.machineReset();
 }
  /**
   * Load a new program into the machine and reset it
   *
   * @param instructions The program to load into the machine
   */
  public void loadInstructions(List<Instruction> instructions) {
    this.instructions = instructions;

    if (instructions != null) {
      int i = 0;
      for (Instruction op : instructions) {
        if (op.name.equals("label")) labels.put((String) op.arg.getValue(), i);
        i++;
      }
    } else instructions = new ArrayList<Instruction>();

    for (StackMachineListener l : listeners) l.programChanged(instructions);
    reset();
  }
 private void notifyListeners() {
   for (StackMachineListener l : listeners) l.stackChanged(this);
 }
 /**
  * Sets the program counter to the next instruction to be executed
  *
  * @param programCounter The line of the next instruction
  */
 private void setProgramCounter(int programCounter) {
   this.programCounter = programCounter;
   for (StackMachineListener l : listeners) l.programCounterChanged(programCounter);
 }
 /**
  * Add a value to the end of the output tape
  *
  * @param value The value to add to the output tape
  */
 public void addOutput(StackValue<?> value) {
   output.add(value);
   for (StackMachineListener l : listeners) l.outputChanged(output.iterator());
 }
 /**
  * Set a particular address in store
  *
  * @param address The address to set
  * @param value The value to set the address to
  * @throws InvalidAddressException
  */
 public void setStore(int address, StackValue<?> value) throws InvalidAddressException {
   if (0 <= address && address < STORE_SIZE) {
     store[address] = value;
     for (StackMachineListener l : listeners) l.storeChanged(address);
   } else throw new InvalidAddressException(address, programCounter);
 }