Asm{{ public static void p(String s){ Console.Error.Write(s); } /*public static void Main(String[] args){ if(args.Length == 0){ p(" ** usage: asm.exe \n"); return; } OpList code = Asm.parse(new System.IO.FileStream(args[0],System.IO.FileMode.Open)).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(Opcode o); public abstract OpList append(OpList ol); public abstract ExecStack eval(ExecStack s); public ExecStack eval(){ return eval(new ExecStack(labels())); } public OpList prepend(Opcode o){ return new OpCons(o,this); } public List labels(){ return labels(new Empty()); } public abstract List labels(List e); }} OpCons{{ public override OpList append(Opcode o){ return new OpCons(first, rest.append(o)); } public override OpList append(OpList ol){ return new OpCons(first, rest.append(ol)); } public override ExecStack eval(ExecStack s){ return first.eval(s,rest); } public override List labels(List e){ return rest.labels((first is Label)? e.push(new Entry(((Label)first).id.ToString(),rest)):e); } }} OpEmpty{{ public override OpList append(Opcode o){ return new OpCons(o, this); } public override OpList append(OpList ol){ return ol; } public override ExecStack eval(ExecStack s){ return s; } public override List labels(List e){ return e; } }} Opcode{{ public abstract ExecStack eval(ExecStack s); public virtual ExecStack eval(ExecStack s, OpList cc){ return cc.eval(eval(s)); } }} MathOp{{ public virtual int op(int l, int r){ throw new Exception("NYI Opcode"); } public override ExecStack eval(ExecStack s){ int r = op(s.top(), s.popRes().top()); return s.popRes().popRes().pushRes(r); } }} Plus {{ public override int op(int l, int r){ return l+r; } }} Minus {{ public override int op(int l, int r){ return l-r; } }} Times {{ public override int op(int l, int r){ return l*r; } }} Divide {{ public override int op(int l, int r){ return l/r; } }} Less {{ public override int op(int l, int r){ return (lr)?1:0; } }} Equal {{ public override int op(int l, int r){ return (l==r)?1:0; } }} And {{ public override int op(int l, int r){ return ((l&r&1)==1)?1:0; } }} Or {{ public override int op(int l, int r){ return ((l|r&1)==1)?1:0; } }} Push {{ public override ExecStack eval(ExecStack s){ return s.pushRes(i); } }} Pop {{ public override ExecStack eval(ExecStack s){ return s.popRes(); } }} Def {{ public override ExecStack eval(ExecStack s){ return s.pushEnv(s.top()).popRes(); } }} Undef{{ public override ExecStack eval(ExecStack s){ return s.popEnv(); } }} Load {{ public override ExecStack eval(ExecStack s){ return s.pushRes(s.load(i)); } }} ControlOp{{ public abstract String Id(); public abstract bool branch(ExecStack s); public override ExecStack eval(ExecStack s){ return s; } public override ExecStack eval(ExecStack s, OpList cc){ if(branch(s)) return s.labels.find(new Find(Id())).pc.eval(s); return cc.eval(s); } class Find : List.Pred{ String id; public Find(String s){ id = s; } public override bool huh(Entry e){ return e.label.Equals(id); } } }} Label{{ public override String Id(){ return ""+id; } public override bool branch(ExecStack s){ return false; } }} Jmp{{ public override String Id(){ return ""+id; } public override bool branch(ExecStack s){ return true; } }} IfZ{{ public override String Id(){ return ""+id; } public override bool branch(ExecStack s){ return (s.top() == 0); } }} ExecStack{{ List env = List.create(), result = List.create(); internal List labels = List.create(); public ExecStack(List e, List r, List l){ env = e; result = r; labels = l; } public ExecStack(List e){ labels = e; } public ExecStack pushEnv(int i){ return make(env.push(i),result); } public ExecStack pushRes(int i){ return make(env,result.push(i)); } public ExecStack popEnv(){ return make(env.pop(),result); } public ExecStack popRes(){ return make(env,result.pop()); } public 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 override String ToString(){ return " Env: ["+env+"]\n"+ " Res: ["+result+"]\n"; } }}