import compile.*; import asm.*; import type.*; import edu.neu.ccs.demeterf.demfgen.lib.*; import edu.neu.ccs.demeterf.*; import edu.neu.ccs.demeterf.util.Util; import java.io.*; // Main Functional Compiler Class public class Compile{ static void p(String s){ System.out.print(s); } public static void main(String[] args) throws Exception{ if(args.length < 1){ p(" usage: Compile <CodeFile>\n"); System.exit(1); } Util.addBuiltIn(ident.class); E e = MainC.parse(new FileInputStream(args[0])).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.getMessage()+"\n\n"); } } public OpList compile(E e){ Traversal comp = new Traversal(new Code3()); return comp.traverse(e, List.<ident>create()); } } // Generate Code for the Base Language (Arithmetic) class Code extends ID{ static OpList empty = new OpEmpty(); static OpList single(Opcode o){ return empty.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 extends Code{ List<ident> update(L let, L.body f, List<ident> s){ return s.push(let.id); } OpList combine(V v, ident id, List<ident> 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 extends Code2{ private int lnum = 0; synchronized int fresh(){ return lnum++; } 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)); } }