/**********************************************
 *  AOSD 10 Submission Files                  *
 *  GenExp.java :                             *
 *    Generates huge expression files for     *
 *    performance testing                     *
 *                                            *
 *********************************************/

import gen.*;
import edu.neu.ccs.demeterf.lib.*;
import edu.neu.ccs.demeterf.*;
import edu.neu.ccs.demeterf.stackless.HeapTrav;
import java.io.FileOutputStream;
import java.io.PrintStream;

public class GenExp{
    static void p(String s){ System.out.println(s); }
    public static void main(String[] args) throws Exception{
        if(args.length < 1){
            p(" usage: java GenExp <depth> <file>");
            return;
        }

        int depth = Integer.parseInt(args[0]);
        Exp e = generate(depth,List.<ident>create());
          
        if(args.length < 2){
            p(" Exp: "+e);
        }else{
            PrintStream p = new PrintStream(new FileOutputStream(args[1]));
            p.print(""+e);
            p.close();
        }
    }

    static int num = 1;
    static ident fresh(){ return new ident("v"+num++); }
    static int rand(int i){ return (int)(Math.random()*i); }
    static Exp generate(int i, List<ident> env){
        if(i == 0){
            return (rand(2) == 1 && !env.isEmpty())?
                new Var(env.lookup(rand(env.length()))):
                new Num(rand(100));
        }else{
            int w = rand(3);
            switch(w){
            case 0:return new Ifz(generate(i-1,env),
                                  generate(i-1,env),
                                  generate(i-1,env));
            case 1:return new Bin(new Sub(),
                                  generate(i-1,env),
                                  generate(i-1,env));
            case 2:
                ident id = fresh();
                return new Def(id,
                               generate(i-1,env),
                               generate(i-1,env.push(id)));
            }
            return new Num(99);
        }

    }
}