import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import name.panitz.fun4u.tree.App;
import name.panitz.fun4u.tree.Definition;
import name.panitz.fun4u.tree.Exp;
import name.panitz.fun4u.tree.FunctionDef;
import name.panitz.fun4u.tree.IfExp;
import name.panitz.fun4u.tree.IntLiteral;
import name.panitz.fun4u.tree.OpExp;
import name.panitz.fun4u.tree.Param;
import name.panitz.fun4u.tree.Program;
import name.panitz.fun4u.tree.Type;
import name.panitz.fun4u.tree.Var;
import name.panitz.fun4u.visitor.CheckParams;
import name.panitz.fun4u.visitor.GenCode;
import name.panitz.fun4u.visitor.GenJava;
import name.panitz.fun4u.visitor.Visitor;


public class Test {

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] _) throws Exception {
		Exp i5 = new IntLiteral(5);
		Exp i0 = new IntLiteral(0);
		Exp i1 = new IntLiteral(1);
		Exp cond = new OpExp(new Var("n"),"==",i0);
		Exp regArg=new OpExp(new Var("n"),"-",i1);
		List<Exp> args = new ArrayList<Exp>();
		args.add(regArg);
		Param p = new Param("n",new Type("int"));
		List<Param> params = new ArrayList<Param>();
		params.add(p);
		Exp facBody
		 =new IfExp
		 	(cond
		 	,i1
			,new OpExp(new Var("n"),"*",new App("fac",args)));
		FunctionDef fac = new FunctionDef
			("fac"
			,params
			,facBody
			,new Type("int"));

		List<Exp> argsFac5 = new ArrayList<Exp>();		
		argsFac5.add(i5);
		Exp fac5 = new App("fac",argsFac5);
		List<Definition> fs = new ArrayList<Definition>();
		fs.add(fac);
		Program prog = new Program(fs,fac5);
		Visitor checker = new CheckParams();
		prog.welcome(checker);
		
		Writer w = new FileWriter("Prog.java");
		Visitor v = new GenJava(w);
		prog.welcome(v);
		w.close();

		GenCode gc = new GenCode();
		prog.welcome(gc);
	}

}
