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

package IR2;

import java.util.*;

public class SimpleInstruction
extends LowInstruction implements HighInstruction {
  protected LValue destination;
  protected RValue source;

  public SimpleInstruction(LValue dest, RValue src)
       throws SemanticTypeException {
         destination = dest;
         source = src;
         next = null;
         if (destination != null && source != null &&
             destination.get_type() != source.get_type())
           throw new SemanticTypeException("incompatible assignment from " +
                                           Typed.typenames[src.get_type()] +
                                           " to " +
                                           Typed.typenames[dest.get_type()]);
  }

  public SimpleInstruction(RValue src) {
    destination = null;
    source = src;
    next = null;
  }

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

  public LowInstruction destructure(LowInstruction next) {
    this.next = next;
    return this;
  }

  /* LowInstruction implementation */
  public String desc() {
    if (destination != null) {
      return "assignment";
    } else {
      return "expression";
    }
  }

  public DelocalizedInstruction do_asm(Codegen c, MethodDescriptor d,
                                       CFG output,
                                       DelocalizedInstruction prev)
  {
    DelocalizedRValue s = source.generate_rvalue_asm(d, c, output);
    if (destination != null)
      destination.generate_lvalue_asm(d, c, output, s);
    
    // Hard to tell what happenned. hmm.
    return output.last();
  } 


  /* Algebraic simplification optimization. */
  public void algebraic_simplify() {
    if (destination != null)
      destination = (LValue) destination.algebraic_simplify();
    source = source.algebraic_simplify();
  }


  /* Walkable implementation. */
  public String node_name() {
    if (destination != null) {
      return "assignment";
    } else {
      return "expression";
    }
  }
  public Enumeration neighbors() {
    if (destination != null)
      return new ShortEnumeration(destination, source);
    else
      return new ShortEnumeration(source);
  }
  public String pretty_print(int indent, boolean recursive) {
    String output = new String();
    for (int i = 0; i < indent; i++) output += " ";
    if (recursive) {
      output += "(simple_instruction\n";
      if (destination != null) {
        output += destination.pretty_print(indent + 2, true);
        for (int i = 0; i < indent + 2; i++) output += " ";
        output += " :=\n";
        if (source == null)
          output += "-error-";
        else
          output += source.pretty_print(indent + 4, true);
      } else {
        if (source == null)
          output += "-error-";
        else
          output += source.pretty_print(indent + 4, true);
      }
      for (int i = 0; i < indent; i++) output += " ";
      output += ") /* simple_instruction */\n";
    } else {
      output += "(simple_instruction)\n";
    }
    return output;
  }


  /* Traversable methods. */
  public void traverse(Traversal t) {
    t.traverse(next);
  }
}
