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

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

/**
 * Root node of everything, direct children are nodes of type FunDecl
 *
 * @version $Id$
 * @author  <A HREF="http://www.berlin.de/~markus.dahm/">M. Dahm</A>
 */
public class ASTProgram extends SimpleNode
implements MiniParserConstants, MiniParserTreeConstants, org.apache.bcel.Constants {
  private ASTFunDecl[] fun_decls; // Children: Function declarations
  private Environment  env;       // Environment contains variables and functions

  ASTProgram(int id) {
    super(id);

    env = new Environment();

    /* Add predefined functions WRITE/READ.
     * WRITE has one arg of type T_INT, both return T_INT.
     */
    ASTIdent   ident  = new ASTIdent("WRITE", T_INT, -1, -1);
    ASTIdent[] args   = { new ASTIdent("", T_INT, -1, -1) }; 
    Function   fun    = new Function(ident, args, true);
    env.put(fun);

    ident = new ASTIdent("READ", T_INT, -1, -1);
    args  = new ASTIdent[0];
    fun   = new Function(ident, args, true);
    env.put(fun);
    
    /* Add predefined idents TRUE/FALSE of type T_BOOLEAN
     */
    ident = new ASTIdent("TRUE", T_BOOLEAN, -1, -1);
    Variable var = new Variable(ident, true);
    env.put(var);

    ident = new ASTIdent("FALSE", T_BOOLEAN, -1, -1);
    var   = new Variable(ident, true);
    env.put(var);
  }

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

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

  /**
   * Overrides SimpleNode.closeNode().
   * Cast children to appropiate type.
   */
  public void closeNode() {
    if(children != null) { // Non-empty program ?
      fun_decls = new ASTFunDecl[children.length];
      System.arraycopy(children, 0, fun_decls, 0, children.length);
      children=null; // Throw away old reference
    }
  }

  /**
   * First pass of parse tree.
   *
   * Put everything into the environment, which is copied appropiately to each
   * recursion level, i.e. each FunDecl gets its own copy that it can further
   * manipulate. 
   *
   * Checks for name clashes of function declarations.
   */
  public ASTProgram traverse() {
    ASTFunDecl f;
    ASTIdent   name;
    String     fname;
    EnvEntry   fun;
    Function   main=null;

    if(fun_decls != null) {
      // Put function names into hash table aka. environment
      for(int i=0; i < fun_decls.length; i++) {
	f     = fun_decls[i];
	name  = f.getName();
	fname = name.getName();
	fun   = env.get(fname); // Lookup in env
	
	if(fun != null)
	  MiniC.addError(f.getLine(), f.getColumn(),
			 "Redeclaration of " + fun + ".");
	else
	  env.put(new Function(name, null)); // `args' will be set by FunDecl.traverse()

	
      }

      // Go for it
      for(int i=0; i < fun_decls.length; i++) {
	fun_decls[i] = fun_decls[i].traverse((Environment)env.clone());
	
	// Look for `main' routine
	fname = fun_decls[i].getName().getName();
	if(fname.equals("main"))
	  main = (Function)env.get(fname);
      }
      
      if(main == null)
	 MiniC.addError(0, 0, "You didn't declare a `main' function.");
      else if(main.getNoArgs() != 0)
	 MiniC.addError(main.getLine(), main.getColumn(), 
			"Main function has too many arguments declared.");
    }

    return this;
  }

  /** 
   * Second pass, determine type of each node, if possible.
   * @return type of expression
   */
  public void eval(int pass) {

    for(int i=0; i < fun_decls.length; i++) {
      fun_decls[i].eval(pass);

      if(pass == 3) { // Final check for unresolved types
	ASTIdent name = fun_decls[i].getName();

	if(name.getType() == T_UNKNOWN)
	  MiniC.addError(name.getColumn(), name.getLine(),
			 "Type of function " + name.getName() +
			 " can not be determined (infinite recursion?).");
      }
    }
  }

  /**
   * Fifth pass, produce Java code.
   */
  public void code(PrintWriter out, String name) {
    out.println("import java.io.BufferedReader;");
    out.println("import java.io.InputStreamReader;");
    out.println("import java.io.IOException;\n");

    out.println("public final class " + name + " {");
    out.println("  private static BufferedReader _in = new BufferedReader" + 
		"(new InputStreamReader(System.in));\n");

    out.println("  private static final int _readInt() throws IOException {\n" +
		"    System.out.print(\"Please enter a number> \");\n" + 
		"    return Integer.parseInt(_in.readLine());\n  }\n");

    out.println("  private static final int _writeInt(int n) {\n" +
		"    System.out.println(\"Result: \" + n);\n    return 0;\n  }\n");

    for(int i=0; i < fun_decls.length; i++)
      fun_decls[i].code(out);

    out.println("}");
  }

  /**
   * Fifth pass, produce Java byte code.
   */
  public void byte_code(ClassGen class_gen, ConstantPoolGen cp) {
    /* private static BufferedReader _in;
     */
    class_gen.addField(new Field(ACC_PRIVATE | ACC_STATIC,
				 cp.addUtf8("_in"),
				 cp.addUtf8("Ljava/io/BufferedReader;"),
				 null, cp.getConstantPool()));

    MethodGen       method;
    Method          m;
    InstructionList il = new InstructionList();
    byte[]          byte_code;
    String          class_name = class_gen.getClassName();

    /* Often used constant pool entries
     */
    int             _in = cp.addFieldref(class_name, "_in", "Ljava/io/BufferedReader;");

    int             out = cp.addFieldref("java.lang.System", "out",
					 "Ljava/io/PrintStream;");

    il.append(new GETSTATIC(out));
    il.append(new PUSH(cp, "Please enter a number> "));
    il.append(new INVOKEVIRTUAL(cp.addMethodref("java.io.PrintStream",
						"print",
						"(Ljava/lang/String;)V")));
    il.append(new GETSTATIC(_in));
    il.append(new INVOKEVIRTUAL(cp.addMethodref("java.io.BufferedReader",
						"readLine",
						"()Ljava/lang/String;")));
    il.append(new INVOKESTATIC(cp.addMethodref("java.lang.Integer",
						"parseInt",
						"(Ljava/lang/String;)I")));
    il.append(InstructionConstants.IRETURN);

    /* private static final int _readInt() throws IOException
     */
    method = new MethodGen(ACC_STATIC | ACC_PRIVATE | ACC_FINAL,
			   Type.INT, Type.NO_ARGS, null,
			   "_readInt", class_name, il, cp);

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

    method.setMaxStack(2);
    class_gen.addMethod(method.getMethod());

    /* private static final int _writeInt(int i) throws IOException
     */
    Type[]   args = { Type.INT };
    String[] argv = { "i" } ;
    il = new InstructionList();
    il.append(new GETSTATIC(out));
    il.append(new NEW(cp.addClass("java.lang.StringBuffer")));
    il.append(InstructionConstants.DUP);
    il.append(new PUSH(cp, "Result: "));
    il.append(new INVOKESPECIAL(cp.addMethodref("java.lang.StringBuffer",
						"<init>",
						"(Ljava/lang/String;)V")));

    il.append(new ILOAD(0));
    il.append(new INVOKEVIRTUAL(cp.addMethodref("java.lang.StringBuffer",
						"append",
						"(I)Ljava/lang/StringBuffer;")));

    il.append(new INVOKEVIRTUAL(cp.addMethodref("java.lang.StringBuffer",
						"toString",
						"()Ljava/lang/String;")));
    
    il.append(new INVOKEVIRTUAL(cp.addMethodref("java.io.PrintStream",
						"println",
						"(Ljava/lang/String;)V")));
    il.append(new PUSH(cp, 0));
    il.append(InstructionConstants.IRETURN); // Reuse objects, if possible

    method = new MethodGen(ACC_STATIC | ACC_PRIVATE | ACC_FINAL,
			   Type.INT, args, argv,
			   "_writeInt", class_name, il, cp);

    method.setMaxStack(4);
    class_gen.addMethod(method.getMethod());

    /* public <init> -- constructor
     */
    il.dispose(); // Dispose instruction handles for better memory utilization

    il = new InstructionList();
    il.append(new ALOAD(0)); // Push `this'
    il.append(new INVOKESPECIAL(cp.addMethodref("java.lang.Object",
						"<init>", "()V")));
    il.append(new RETURN());

    method = new MethodGen(ACC_PUBLIC, Type.VOID, Type.NO_ARGS, null,
			   "<init>", class_name, il, cp);
    
    method.setMaxStack(1);
    class_gen.addMethod(method.getMethod());

    /* class initializer
     */
    il.dispose(); // Dispose instruction handles for better memory utilization
    il = new InstructionList();
    il.append(new NEW(cp.addClass("java.io.BufferedReader")));
    il.append(InstructionConstants.DUP);
    il.append(new NEW(cp.addClass("java.io.InputStreamReader")));
    il.append(InstructionConstants.DUP);
    il.append(new GETSTATIC(cp.addFieldref("java.lang.System", "in",
					   "Ljava/io/InputStream;")));
    il.append(new INVOKESPECIAL(cp.addMethodref("java.io.InputStreamReader",
						"<init>", "(Ljava/io/InputStream;)V")));
    il.append(new INVOKESPECIAL(cp.addMethodref("java.io.BufferedReader",
						"<init>", "(Ljava/io/Reader;)V")));
    il.append(new PUTSTATIC(_in));
    il.append(InstructionConstants.RETURN); // Reuse instruction constants

    method = new MethodGen(ACC_STATIC, Type.VOID, Type.NO_ARGS, null,
			   "<clinit>", class_name, il, cp);

    method.setMaxStack(5);
    class_gen.addMethod(method.getMethod());

    for(int i=0; i < fun_decls.length; i++)
      fun_decls[i].byte_code(class_gen, cp);
  }

  public void dump(String prefix) {
    System.out.println(toString(prefix));

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