Opcodes ParseOpcode(string operation, OpcodeFlags flags) { Func <bool> no = () => flags == OpcodeFlags.NoOperands; Func <bool> ra = () => flags.HasFlag(OpcodeFlags.Register1); Func <bool> rb = () => flags.HasFlag(OpcodeFlags.Register2); Func <bool> la = () => flags.HasFlag(OpcodeFlags.Literal1); Func <bool> lb = () => flags.HasFlag(OpcodeFlags.Literal2); Func <Opcodes, Opcodes, Opcodes, Opcodes, Opcodes> RR_LR_RL_LL = (rr, lr, rl, ll) => { if (ra() & rb()) { return(rr); } else if (ra() & lb()) { return(rl); } else if (la() & rb()) { return(lr); } else if (la() & la()) { return(ll); } else { InvalidOperands(); return(Opcodes.nop); } }; Func <Opcodes, Opcodes, Opcodes> RR_LR = (rr, lr) => { if (ra() & rb()) { return(rr); } if (la() & rb()) { return(lr); } else { InvalidOperands(); return(Opcodes.nop); } }; Func <Opcodes, Opcodes, Opcodes> RR_RL = (r, l) => { if (ra() & rb()) { return(r); } else if (ra() & lb()) { return(l); } else { InvalidOperands(); return(Opcodes.nop); } }; Func <Opcodes, Opcodes> NoOps = o => { if (no()) { return(o); } else { InvalidOperands(); return(Opcodes.nop); } }; Func <Opcodes, Opcodes> LR = l => { if (lb() | ra()) { InvalidOperands(); } if (la() & rb()) { return(l); } else { InvalidOperands(); return(Opcodes.nop); } }; Func <Opcodes, Opcodes, Opcodes> R_L = (r, l) => { if (rb() | lb()) { InvalidOperands(); } if (ra()) { return(r); } else if (la()) { return(l); } else { InvalidOperands(); return(Opcodes.nop); } }; Func <Opcodes, Opcodes> R = (r) => { if (rb() | lb() | la()) { InvalidOperands(); } if (ra()) { return(r); } else { InvalidOperands(); return(Opcodes.nop); } }; Func <Opcodes, Opcodes> L = (l) => { if (rb() | lb() | ra()) { InvalidOperands(); } if (la()) { return(l); } else { InvalidOperands(); return(Opcodes.nop); } }; switch (operation) { case "nop": return(NoOps(Opcodes.nop)); case "read": return(RR_RL(Opcodes.readr, Opcodes.readl)); case "write": return(RR_LR_RL_LL(Opcodes.writerr, Opcodes.writelr, Opcodes.writerl, Opcodes.writell)); case "push": return(R_L(Opcodes.pushr, Opcodes.pushl)); case "mov": return(RR_RL(Opcodes.movr, Opcodes.movl)); case "add": return(RR_RL(Opcodes.addr, Opcodes.addl)); case "sub": return(RR_RL(Opcodes.subr, Opcodes.subl)); case "mult": return(RR_RL(Opcodes.multr, Opcodes.multl)); case "div": return(RR_RL(Opcodes.divr, Opcodes.divl)); case "mod": return(RR_RL(Opcodes.modr, Opcodes.modl)); case "and": return(RR_RL(Opcodes.andr, Opcodes.andl)); case "or": return(RR_RL(Opcodes.orr, Opcodes.orl)); case "xor": return(RR_RL(Opcodes.xorr, Opcodes.xorl)); case "not": return(R(Opcodes.not)); case "neg": return(R(Opcodes.neg)); case "pop": return(R(Opcodes.pop)); case "pusha": return(NoOps(Opcodes.pusha)); case "popa": return(NoOps(Opcodes.popa)); case "hlt": return(NoOps(Opcodes.hlt)); case "int": return(R_L(Opcodes.intr, Opcodes.intl)); case "call": return(R_L(Opcodes.callr, Opcodes.calll)); case "jmp": return(R_L(Opcodes.jmpr, Opcodes.jmpl)); case "je": return(L(Opcodes.je)); case "jne": return(L(Opcodes.jne)); case "jg": return(L(Opcodes.jg)); case "jge": return(L(Opcodes.jge)); case "jl": return(L(Opcodes.jl)); case "jle": return(L(Opcodes.jle)); case "cmp": return(RR_RL(Opcodes.cmpr, Opcodes.cmpl)); case "ret": return(NoOps(Opcodes.ret)); case "deref": return(RR_RL(Opcodes.derefr, Opcodes.derefl)); case "brk": return(NoOps(Opcodes.brk)); case "cpuid": return(NoOps(Opcodes.cpuid)); case "out": return(NoOps(Opcodes._out)); case "in": return(NoOps(Opcodes._in)); case "sa": return(RR_LR_RL_LL(Opcodes.sarr, Opcodes.salr, Opcodes.sarl, Opcodes.sall)); case "sai": return(R_L(Opcodes.sair, Opcodes.sail)); case "inca": return(NoOps(Opcodes.inca)); case "deca": return(NoOps(Opcodes.deca)); case "ls": return(RR_RL(Opcodes.lsr, Opcodes.lsl)); case "rs": return(RR_RL(Opcodes.rsr, Opcodes.rsl)); } RaiseError(string.Format("Invalid instruction \"{0}\"", operation)); return(Opcodes.nop); }
void ParseInstruction(string line) { Match match = Regex.Match(line, instructionCapture); string operation = match.Groups[1].Value; string opA = match.Groups[2].Value; string opB = match.Groups[4].Value; uint16_t operandA = Int.UInt16; uint16_t operandB = Int.UInt16; OpcodeFlags flags = OpcodeFlags.NoOperands; Func <bool> era = () => { uint16_t temp; if (ExpectRegister(opA, out temp)) { operandA = temp; return(true); } else { return(false); } }; Func <bool> erb = () => { uint16_t temp; if (ExpectRegister(opB, out temp)) { operandB = temp; return(true); } else { return(false); } }; Func <bool> ela = () => { uint16_t temp; if (ExpectLiteral(opA, out temp)) { operandA = temp; return(true); } else { return(false); } }; Func <bool> elb = () => { uint16_t temp; if (ExpectLiteral(opB, out temp)) { operandB = temp; return(true); } else { return(false); } }; Func <bool> esa = () => { uint16_t temp; if (flags.HasFlag(OpcodeFlags.Literal1)) { return(false); } if (ExpectSymbol(opA, out temp)) { operandA = temp; return(true); } else { return(false); } }; Func <bool> esb = () => { uint16_t temp; if (flags.HasFlag(OpcodeFlags.Literal2)) { return(false); } if (ExpectSymbol(opB, out temp)) { operandB = temp; return(true); } else { return(false); } }; try { if (era()) { flags = flags | OpcodeFlags.Register1; } if (erb()) { flags = flags | OpcodeFlags.Register2; } if (ela()) { flags = flags | OpcodeFlags.Literal1; } if (elb()) { flags = flags | OpcodeFlags.Literal2; } if (esa()) { flags = flags | OpcodeFlags.Literal1; } if (esb()) { flags = flags | OpcodeFlags.Literal2; } Opcodes opcode = ParseOpcode(operation, flags); Opcode oc = new Opcode(opcode, flags, operandA, operandB); buildList.Add(string.Format("${0}", opcodes.Count)); opcodes.Add(oc); address += 8; } catch { throw; } }