using System; namespace NPhilosopher { public variant NComparison { | EQ | NE | GT | LT | GTE | LTE } public variant NStack { | Add | Sub | Mul | Div | Mod | Neg | And | Or | Xor | Not | Shl | Shr | Push { PushValue : object; } | PushArg { Arg : int; } | Pop | Dup | Call { CallTarget : object; } | CallVirt { VirtTarget : object; } | Ret | CondBranch { Taken : object; NotTaken : object; Comparison : NComparison; Signed : bool; } } public module CILToStack { public ConvertInst(inst : NIL.Inst) : NStack { | Inst(_, _, opcd, _, arg) => match(opcd) { | 0x0000U => null; | 0x0002U => NStack.PushArg(0); | 0x0003U => NStack.PushArg(1); | 0x0004U => NStack.PushArg(2); | 0x0005U => NStack.PushArg(3); | 0x0028U => NStack.Call(CA(arg)); | 0x002AU => NStack.Ret(); | 0x0058U => NStack.Add(); | 0x0059U => NStack.Sub(); | 0x005AU => NStack.Mul(); | 0x005BU => NStack.Div(); | 0x0065U => NStack.Neg(); | 0x005FU => NStack.And(); | 0x006FU => NStack.CallVirt(CA(arg)); | 0x0072U => NStack.Push(CA(arg)); | _ => throw Exception(String.Format("Unknown opcode {0:X}", opcd)); } } CA(arg : NIL) : object { | Int(val) => val : object; | UInt(val) => val : object; | Object(obj) => obj : object; | x => x; } } }