using compile; using asm; using type; using edu.neu.ccs.demeterf.demfgen.lib; using edu.neu.ccs.demeterf; using System.IO; using System; // Main Functional Compiler Class public class Compile{ static void p(String s){ Console.Write(s); } public static void Main(String[] args){ if(args.Length < 1){ p(" usage: compile.exe \n"); return; } E e = MainC.parse(new FileStream(args[0],FileMode.Open)).e; try{ p("\n Exp: "+e.Print()+"\n"); p("\n Type: "+TypeCheck.check(e).Print()+"\n"); OpList code = new Compile().compile(e); p("\n Code:\n"+code.Print()+"\n"); ExecStack res = code.eval(); p("\n Eval: "+(res.top())+"\n"); p("\n Stacks: \n"+res+"\n"); }catch(TypeCheck.TE ex){ p("\n TypeError: "+ex.Message+"\n\n"); } } public OpList compile(E e){ Traversal comp = new Traversal(new Code3()); return comp.traverse(e, List.create()); } } // Generate Code for the Base Language (Arithmetic) class Code : ID{ public static OpList single(Opcode o){ return new OpEmpty().append(o); } OpList combine(P p){ return single(new Plus()); } OpList combine(M m){ return single(new Minus()); } OpList combine(T t){ return single(new Times()); } OpList combine(D d){ return single(new Divide()); } OpList combine(S s, int i){ return single(new Push(i)); } OpList combine(C c, OpList op, OpList left, OpList right){ return right.append(left).append(op); } } // Generate Code with the Let/de Bruijn Extension class Code2 : Code{ List update(L let, L.bodyF f, List s){ return s.push(let.id); } OpList combine(V v, ident id, List s){ return single(new Load(s.index(id))); } OpList combine(L let, ident id, OpList e, OpList body){ return e.append(new Def()).append(body).append(new Undef()); } } // Generate Code for Boolean Functions and If expressions class Code3 : Code2{ private int lnum = 0; int fresh(){ int i; lock(this)i = lnum++; return i; } OpList combine(LT l){ return single(new Less()); } OpList combine(GT g){ return single(new Greater()); } OpList combine(EQ e){ return single(new Equal()); } OpList combine(AndF a){ return single(new And()); } OpList combine(OrF o){ return single(new Or()); } OpList combine(I f, OpList c, OpList t, OpList e){ ident l1 = new ident("else_"+fresh()), l2 = new ident("done_"+fresh()); return c.append(new IfZ(l1)).append(t) .append(new Jmp(l2)).append(new Label(l1)) .append(e).append(new Label(l2)); } }