/********************************************** * AOSD 10 Submission Files * * asm.beh : * * Contains all the Asm methods/behavior * * * *********************************************/ Asm{{ public static void p(String s){ System.out.print(s); } public static void main(String args[]) throws Exception { OpList code = Asm.parse(System.in).c; p("\n OpCodes: \n"+code.print()+"\n"); List labels = code.labels(); p("\n Eval = "+(code.eval(new ExecStack(labels)).top())+"\n"); } }} OpList{{ public abstract OpList append(Op o); public abstract OpList append(OpList ol); public abstract ExecStack eval(ExecStack s); public ExecStack eval(){ return eval(new ExecStack(labels())); } public OpList prepend(Op o){ return new OpCons(o,this); } public List labels(){ return labels(List.create()); } abstract List labels(List e); public static OpList fromList(List l){ if(l.isEmpty())return new OpEmpty(); return fromList(l.pop()).prepend(l.top()); } }} OpCons{{ public OpList append(Op o){ return new OpCons(first, rest.append(o)); } public OpList append(OpList ol){ return new OpCons(first, rest.append(ol)); } public ExecStack eval(ExecStack s){ return first.eval(s,rest); } List labels(List e){ return rest.labels((first instanceof Label)? e.push(new CodeEntry(((Label)first).id.toString(),rest)):e); } }} OpEmpty{{ public OpList append(Op o){ return new OpCons(o, this); } public OpList append(OpList ol){ return ol; } public ExecStack eval(ExecStack s){ return s; } List labels(List e){ return e; } }} Op{{ static OpList mt = new OpEmpty(); abstract ExecStack eval(ExecStack s); ExecStack eval(ExecStack s, OpList cc){ return cc.eval(eval(s)); } public OpList append(Op o){ return mt.append(this).append(o); } public OpList append(OpList o){ return mt.append(this).append(o); } }} MathOp{{ int op(int l, int r){ throw new RuntimeException("NYI Opcode"); } ExecStack eval(ExecStack s){ int r = op(s.top(), s.popRes().top()); return s.popRes().popRes().pushRes(r); } }} Plus {{ int op(int l, int r){ return l+r; } }} Minus {{ int op(int l, int r){ return l-r; } }} Times {{ int op(int l, int r){ return l*r; } }} Divide {{ int op(int l, int r){ return l/r; } }} Less {{ int op(int l, int r){ return (lr)?1:0; } }} Equal {{ int op(int l, int r){ return (l==r)?1:0; } }} And {{ int op(int l, int r){ return ((l&r&1)==1)?1:0; } }} Or {{ int op(int l, int r){ return ((l|r&1)==1)?1:0; } }} Push {{ ExecStack eval(ExecStack s){ return s.pushRes(i); } }} Pop {{ ExecStack eval(ExecStack s){ return s.popRes(); } }} Define {{ ExecStack eval(ExecStack s){ return s.pushEnv(s.top()).popRes(); } }} Undef {{ ExecStack eval(ExecStack s){ return s.popEnv(); } }} Load {{ ExecStack eval(ExecStack s){ return s.pushRes(s.load(i)); } }} CtrlOp{{ abstract String id(); abstract boolean branch(ExecStack s); ExecStack eval(ExecStack s){ return s; } ExecStack eval(ExecStack s, OpList cc){ if(branch(s)) return s.labels.find(new Find(id())).pc.eval(s); return cc.eval(s); } static class Find extends List.Pred{ String id; Find(String s){ id = s; } public boolean huh(CodeEntry e){ return e.label.equals(id); } } }} Label{{ String id(){ return ""+id; } boolean branch(ExecStack s){ return false; } }} Jmp{{ String id(){ return ""+id; } boolean branch(ExecStack s){ return true; } }} IfZ{{ String id(){ return ""+id; } boolean branch(ExecStack s){ return (s.top() == 0); } }} IfNZ{{ String id(){ return ""+id; } boolean branch(ExecStack s){ return (s.top() != 0); } }} ExecStack{{ List env = List.create(), result = env; List labels = List.create(); public ExecStack(List e, List r, List l) { env = e; result = r; labels = l; } public ExecStack(List e){ this(); labels = e; } ExecStack pushEnv(int i){ return make(env.push(i),result); } ExecStack pushRes(int i){ return make(env,result.push(i)); } ExecStack popEnv(){ return make(env.pop(),result); } ExecStack popRes(){ return make(env,result.pop()); } int load(int i){ return env.lookup(i); } public int top(){ return result.top(); } ExecStack make(List e, List r) { return new ExecStack(e,r,labels); } public String toStr(){ return " Env: ["+env+"]\n"+ " Res: ["+result+"]\n"; } }}