/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * Compile.java * * Compiler code for AOSD-09 submission * * * * - Functional Adaptive Programming * * - Bryan Chadwick and Karl Lieberherr * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ using System; // Import generated code using lang; // Import DemeterF Library using edu.neu.ccs.demeterf.lib; using edu.neu.ccs.demeterf; using edu.neu.ccs.demeterf.parallel; // IO for file input using System.IO; // Main Functional Compiler Class public class Compile{ // Shorted print method static void p(String s){ Console.WriteLine(s); } // List of valid options static List<String> valid = List<String>.create("seq","par"); // Main Method public static void Main(String[] args){ if(args.Length < 1){ p(" usage: Compile <CodeFile> [par|seq]"); return; } // Read an expression from the given file and: // 1) Simplify/Compile/Eval and print results, or // 2) Run timed compile par/seq test based on the // second argument exp e = main.parse(new FileStream(args[0], FileMode.Open)).e; if(args.Length == 1){ p("\nExp:\n\n"+e); p("\nEval: "+e.eval()); p("\nEval: "+Eval.eval(e)); e = ConstProp.simplify(e); p("\nSimpler:\n\n"+e); p("\nEval: "+e.eval()); List<Op> code = parcompile(e); p("\nCode:\n"+code.ToString("\n"," ")); ExecStack res = OpList.fromList(code).eval(); p("\nEval: "+(res.top())); p("\nStacks: \n"+res.toStr()); return; } // Which one... par/seq int type = valid.index(args[1]); // Start time DateTime st = DateTime.Now; switch(type){ case 0:seqcompile(e);p("Seq");break; case 1:parcompile(e);p("Par");break; } // Print the total time TimeSpan tm = DateTime.Now - st; p(""+(tm.Seconds*1000+tm.Milliseconds)); } // Sequential static List<Op> seqcompile(exp e){ return new Traversal(new Ctrl()) .traverse<List<Op>>(e, List<ident>.create()); } // Parallel static List<Op> parcompile(exp e){ return new ParTraversal(new Ctrl()) .traverse<List<Op>>(e, List<ident>.create()); } } // Generate code for the Base Language (Arithmetic) class Math : ID{ static List<Op> empty = List<Op>.create(); public static List<Op> one(Op o){ return empty.append(o); } List<Op> combine(sub p){ return one(new Minus()); } List<Op> combine(num n, int i){ return one(new Push(i)); } List<Op> combine(bin b, List<Op> o, List<Op> l, List<Op> r){ return r.append(l).append(o); } } // Generate code for the Stack operations (push/def/undef) class Stk : Math{ List<ident> update(def d, def.bodyF f, List<ident> s){ return s.push(d.id); } List<Op> combine(var v, ident id, List<ident> s){ return one(new Load(s.index(id))); } List<Op> combine(def d, ident id, List<Op> e, List<Op> b){ return e .append(new Def()) .append(b) .append(new Undef()); } } // Generate code for "ifz" conditional/control ops class Ctrl : Stk{ private int lnum = 0; ident fresh(String s) { lock(this)return new ident(s+"_"+lnum++); } List<Op> combine(ifz f, List<Op> c, List<Op> t, List<Op> e){ ident le = fresh("else"), ld = fresh("done"); return c .append(new IfNZ(le)) .append(t) .append(new Jmp(ld)) .append(new Label(le)) .append(e) .append(new Label(ld)); } } // Expression simplification/Constant propogation class ConstProp : Bc{ class zero : num{ public zero() : base(0) {} public override String ToString(){ return "zero"; }} num combine(num n, int i) { return (i==0) ? new zero() : n; } exp combine(bin b, sub p, exp l, zero r){ return l; } exp combine(bin b, sub p, num l, zero r){ return l; } exp combine(bin b, sub p, num l, num r){ return new num(l.val-r.val); } exp combine(ifz f, zero z, exp t, exp e){ return t; } exp combine(ifz f, num n, exp t, exp e){ return e; } public static exp simplify(exp e){ return new Traversal(new ConstProp()) .traverse<exp>(e); } }