// $Id: WhileInstruction.java,v 1.1.1.1 1999/12/05 22:19:52 mpp Exp $

package IR2;

import java.util.*;

public class WhileInstruction implements HighInstruction {
  protected RValue loop_condition;
  protected Block block;

  public WhileInstruction(RValue lc, Block b) throws SemanticTypeException {
    loop_condition = lc;
    block = b;
    if (lc != null && lc.get_type() != Typed.BOOLEAN)
      throw new SemanticTypeException("non-boolean expression in conditional "+
				      "of while block");  
  }

  /* Instruction implementation. */
  public Enumeration subblocks() {
    return new ShortEnumeration(block);
  }

  public LowInstruction destructure(LowInstruction next) {
    NopInstruction beginning = new NopInstruction();
    beginning.add_label();
    beginning.next =
      loop_condition.short_circuit(block.destructure(beginning), next);
    return beginning;
  }

  /* Walkable implementation. */
  public String node_name() {
    return "while_instruction";
  }

  public Enumeration neighbors() {
    return new ShortEnumeration(this.loop_condition, block);
  }

  public String pretty_print(int indent, boolean recursive) {
    String output = new String();
	
    for (int i = 0; i < indent; i++) output += " ";
    if (recursive) {
      indent += 2;
      output += "(" + this.node_name() + "\n";
      /* stuff - calls to prettyprints of internals of this node*/
      for (Enumeration e = this.neighbors(); e.hasMoreElements();) {
	Walkable foo = (Walkable)e.nextElement();
	if (foo == null) 
	  output += "-error-";
	else
	  output += foo.pretty_print(indent, true);
      }
      for (int i = 0; i < indent; i++) output += " ";
      output += ") /* "+ this.node_name() + " */\n";
    } else {
      output += "(" + this.node_name() + ")\n";
    }
    return output;
  }
}
