/* Generated By:JJTree: Do not edit this line. ASTFunDecl.java */
/* JJT: 0.3pre1 */

package Mini;
import java.io.PrintWriter;
import java.util.Iterator;
import org.apache.bcel.classfile.*;
import org.apache.bcel.generic.*;
import org.apache.bcel.util.InstructionFinder;

/**
 *
 * @version $Id$
 * @author  <A HREF="http://www.berlin.de/~markus.dahm/">M. Dahm</A>
 */
public class ASTFunDecl extends SimpleNode
implements MiniParserTreeConstants, org.apache.bcel.Constants {
  private ASTIdent    name;
  private ASTIdent[]  argv;
  private ASTExpr     body;
  private int         type = T_UNKNOWN;
  private int         line, column; 
  private boolean     is_simple;  // true, if simple expression like `12 + f(a)'
  private boolean     is_recursive; // Not used yet, TODO
  private int         max_depth; // max. expression tree depth
  private Environment env;

  // Generated methods
  ASTFunDecl(int id) {
    super(id);
  }

  ASTFunDecl(MiniParser p, int id) {
    super(p, id);
  }

  public static Node jjtCreate(MiniParser p, int id) {
    return new ASTFunDecl(p, id);
  }

  ASTFunDecl(ASTIdent name, ASTIdent[] argv, ASTExpr body, int type) {
    this(JJTFUNDECL);
    
    this.name = name;
    this.argv = argv;
    this.body = body;
    this.type = type;
  }
  
  /**
   * Overrides SimpleNode.closeNode()
   * Cast children to appropiate type.
   */
  public void closeNode() {
    name = (ASTIdent)children[0];
    body = (ASTExpr)children[children.length - 1];

    argv = new ASTIdent[children.length - 2]; // May be 0-size array
    for(int i = 1; i < children.length - 1; i++)
      argv[i - 1] = (ASTIdent)children[i];

    children=null; // Throw away old reference
  }

  /**
   * First pass of parse tree.
   */
  public ASTFunDecl traverse(Environment env) {
    this.env = env;

    // Put arguments into hash table aka environment
    for(int i=0; i < argv.length; i++) {
      EnvEntry entry = env.get(argv[i].getName());

      if(entry != null)
	MiniC.addError(argv[i].getLine(), argv[i].getColumn(),
		       "Redeclaration of " + entry + ".");
      else 
	env.put(new Variable(argv[i]));
    }

    /* Update entry of this function, i.e. set argument references.
     * The entry is already in there by garantuee, but may be of wrong type,
     * i.e. the user defined a function `TRUE', e.g. and `TRUE' is of type `Variable'.
     */   
    try {
      Function fun = (Function)env.get(name.getName());
      fun.setArgs(argv);
    } catch(ClassCastException e) {} // Who cares?
    
    body = body.traverse(env); // Traverse expression body

    return this;
  }

  /** Second pass
   * @return type of expression
   */
  public int eval(int pass) {
    int expected = name.getType(); // Maybe other function has already called us
    type = body.eval(expected);    // And updated the env

    if((expected != T_UNKNOWN) && (type != expected))
      MiniC.addError(line, column,
		     "Function f ist not of type " + TYPE_NAMES[expected] + 
		     " as previously assumed, but " + TYPE_NAMES[type]);

    name.setType(type);

    is_simple = body.isSimple();

    if(pass == 2 && type == T_UNKNOWN)
      is_recursive = true;

    return type;
  }

  /**
   * Fourth pass, produce Java code.
   */
  public void code(PrintWriter out) {
    String expr;
    boolean main=false, ignore=false;

    String fname = name.getName();

    if(fname.equals("main")) {
      out.println("  public static void main(String[] _argv) {");
      main = true;
    }
    else if(fname.equals("READ") || fname.equals("WRITE")) { // Do nothing
      ignore = true;
    }
    else {
      out.print("  public static final " + "int" + // type_names[type] +
		" " + fname + "(");
      
      for(int i = 0; i < argv.length; i++) {
	out.print("int " + argv[i].getName());
	
	if(i < argv.length - 1)
	  out.print(", ");
      }
      
      out.println(")\n    throws IOException\n  {");
    }
    
    if(!ignore) {
      StringBuffer buf = new StringBuffer();

      body.code(buf);
      out.println(getVarDecls());

      expr = buf.toString();

      if(main)
	out.println("    try {");

      out.println(expr);

      if(main)
	out.println("    } catch(Exception e) { System.err.println(e); }\n  }\n");
      else
	out.println("\n    return " + pop() + ";\n  }\n");
    }

    reset();
  }

  /**
   * Fifth pass, produce Java byte code.
   */
  public void byte_code(ClassGen class_gen, ConstantPoolGen cp) {
    MethodGen method=null;
    boolean main=false, ignore=false;
    String class_name = class_gen.getClassName();
    String fname      = name.getName();
    InstructionList il = new InstructionList();

    Type[] args = { new ArrayType(Type.STRING, 1) }; // default for `main'
    String[] arg_names = { "$argv" };

    if(fname.equals("main")) {
      method = new MethodGen(ACC_STATIC | ACC_PUBLIC,
			     Type.VOID, args, arg_names,
			     "main", class_name, il, cp);

      main = true;
    } else if(fname.equals("READ") || fname.equals("WRITE")) { // Do nothing
      ignore = true;
    } else {
      int    size  = argv.length;

      arg_names = new String[size];
      args      = new Type[size];

      for(int i = 0; i < size; i++) {
	args[i] = Type.INT;
	arg_names[i] =  argv[i].getName();
      }

      method = new MethodGen(ACC_STATIC | ACC_PRIVATE | ACC_FINAL,
			     Type.INT, args, arg_names,
			     fname, class_name, il, cp);

      LocalVariableGen[] lv = method.getLocalVariables();
      for(int i = 0; i < size; i++) {
	Variable entry = (Variable)env.get(arg_names[i]);
	entry.setLocalVariable(lv[i]);
      }

      method.addException("java.io.IOException");
    }

    if(!ignore) {
      body.byte_code(il, method, cp);

      if(main) {
	ObjectType e_type = new ObjectType("java.lang.Exception");
	InstructionHandle start = il.getStart(), end, handler, end_handler;
	LocalVariableGen exc = method.addLocalVariable("$e",
						       e_type,
						       null, null);
	int slot = exc.getIndex();

	il.append(InstructionConstants.POP); pop(); // Remove last element on stack
	end = il.append(InstructionConstants.RETURN); // Use instruction constants, if possible

	// catch
	handler = il.append(new ASTORE(slot)); // save exception object
	il.append(new GETSTATIC(cp.addFieldref("java.lang.System", "err",
					       "Ljava/io/PrintStream;")));
	il.append(new ALOAD(slot)); push(2);
	il.append(new INVOKEVIRTUAL(cp.addMethodref("java.io.PrintStream",
						"println",
						"(Ljava/lang/Object;)V")));
	pop(2);
	end_handler = il.append(InstructionConstants.RETURN);
	method.addExceptionHandler(start, end, handler, e_type);
	exc.setStart(handler); exc.setEnd(end_handler);
      }
      else
	il.append(InstructionConstants.IRETURN); // Reuse object to save memory

      method.removeNOPs(); // First optimization pass, provided by MethodGen
      optimizeIFs(il);     // Second optimization pass, application-specific
      method.setMaxStack(max_size);
      class_gen.addMethod(method.getMethod());
    }

    il.dispose(); // Dispose instruction handles for better memory utilization

    reset();
  }

  private static final InstructionFinder.CodeConstraint my_constraint =
    new InstructionFinder.CodeConstraint() {
      public boolean checkCode(InstructionHandle[] match) {
	BranchInstruction if_icmp = (BranchInstruction)match[0].getInstruction();
	GOTO              goto_   = (GOTO)match[2].getInstruction();
	return (if_icmp.getTarget() == match[3]) && (goto_.getTarget() == match[4]);
      }
    };

  /**
   * Replaces instruction sequences (typically generated by ASTIfExpr) of the form
   *
   * IF_ICMP__, ICONST_1, GOTO, ICONST_0, IFEQ, Instruction
   *
   * where the IF_ICMP__ branches to the ICONST_0 (else part) and the GOTO branches
   * to the IFEQ with the simpler expression
   *
   * IF_ICMP__, Instruction
   *
   * where the IF_ICMP__ now branches to the target of the previous IFEQ instruction.
   */
  private static final void optimizeIFs(InstructionList il) {
    InstructionFinder f   = new InstructionFinder(il);
    String      pat = "IF_ICMP ICONST_1 GOTO ICONST_0 IFEQ Instruction";

    for(Iterator it = f.search(pat, my_constraint); it.hasNext();) {
      InstructionHandle[] match = (InstructionHandle[])it.next();
      int len = match.length;

      // Everything ok, update code
      BranchInstruction ifeq    = (BranchInstruction)(match[4].getInstruction());
      BranchHandle      if_icmp = (BranchHandle)match[0];

      if_icmp.setTarget(ifeq.getTarget());

      try {
	il.delete(match[1], match[4]);
      } catch(TargetLostException e) {
	InstructionHandle[] targets = e.getTargets();

	System.err.println(targets[0]);

	for(int i=0; i < targets.length; i++) {
	  InstructionTargeter[] targeters = targets[i].getTargeters();

	  for(int j=0; j < targeters.length; j++)
	    if((targets[i] != match[4]) || (targeters[j] != match[2]))
	      System.err.println("Ooops: " + e);
	}
      }
    }
  }

  /**
   * Overrides SimpleNode.toString()
   */
  public String toString() {
    StringBuffer buf = new StringBuffer();
    buf.append(jjtNodeName[id] + " " + name + "(");

    for(int i = 0; i < argv.length; i++) {
      buf.append(argv[i].getName());
      if(i < argv.length - 1)
	buf.append(", ");
    }

    buf.append(")");
    return buf.toString();
  }

  public boolean    isrecursive()         { return is_recursive; }
  public boolean    isSimple()            { return is_simple; }
  public ASTIdent   getName()             { return name; }
  public int        getNoArgs()           { return argv.length; }
  public ASTIdent[] getArgs()             { return argv; }
  public int        getType()             { return type; }
  public void       setType(int type)     { this.type = type; }
  public void       setLine(int line)     { this.line = line; }
  public int        getLine()             { return line; }
  public void       setColumn(int column) { this.column = column; }
  public int        getColumn()           { return column; }
  public void       setPosition(int line, int column) {
    this.line = line;
    this.column = column;
  }

  /**
   * Overrides SimpleNode.dump()
   */
  public void dump(String prefix) {
    System.out.println(toString(prefix));

    for(int i = 0; i < argv.length; i++)
      argv[i].dump(prefix + " ");

    body.dump(prefix + " ");
  }

  /* Used to simpulate stack with local vars and compute maximum stack size.
   */
  static int size, max_size;

  static final void reset() { size = max_size = 0; }

  private static final String getVarDecls() {
    StringBuffer buf = new StringBuffer("    int ");

    for(int i=0; i < max_size; i++) {
      buf.append("_s" + i);

      if(i < max_size - 1)
	buf.append(", ");
    }

    buf.append(";\n");
    return buf.toString();
  }

  /** Used by byte_code()
   */
  static final void pop(int s) { size -= s; }
  static final void push(int s) {
    size += s;

    if(size > max_size)
      max_size = size;
  }
  static final void push() { push(1); }

  /** Used byte code()
   */
  static final void push(StringBuffer buf, String str) {
    buf.append("    _s" + size + " = " + str + ";\n");
    push(1);
  }

  static final String pop() {
    return "_s" + (--size);
  }
}
