public Instruction ParseSingle(ParseState ParseState) { var InstructionPosition = Stream.Position; var OpcodeNum = BinaryReader.ReadUInt16(); if (!Opcodes.ContainsKey(OpcodeNum)) { throw(new NotImplementedException(String.Format("Unhandled opcode 0x{0:X2}", OpcodeNum))); } var Opcode = Opcodes[OpcodeNum]; var Params = new List <object>(); foreach (var FormatChar in Opcode.Format) { switch (FormatChar) { case '<': break; case 's': Params.Add(ReadString()); break; case 'S': Params.Add(ReadStringz()); break; case '1': Params.Add(BinaryReader.ReadByte()); break; case '7': Params.Add((AritmeticOps)BinaryReader.ReadByte()); break; case '9': Params.Add((ComparisionOps)BinaryReader.ReadByte()); break; case '2': Params.Add(BinaryReader.ReadInt16()); break; case 'v': Params.Add(new VariableReference() { Index = BinaryReader.ReadUInt16() }); break; case '4': Params.Add(BinaryReader.ReadUInt32()); break; case 'L': Params.Add(new LabelReference() { Offset = BinaryReader.ReadUInt32() }); break; case 'P': { var ParamType = BinaryReader.ReadByte(); object Value = null; switch (ParamType) { case 0x00: Value = BinaryReader.ReadSByte(); break; case 0x10: Value = BinaryReader.ReadByte(); break; case 0x20: Value = BinaryReader.ReadInt16(); break; case 0x40: Value = BinaryReader.ReadInt32(); break; case 0x01: Value = new VariableReference() { Index = BinaryReader.ReadUInt16() }; break; case 0x02: Value = new SpecialReference() { Index = BinaryReader.ReadUInt16() }; break; default: throw (new NotImplementedException(String.Format("Invalid param type {0}", ParamType))); } Params.Add(Value); } break; default: throw(new NotImplementedException(String.Format("Invalid format '{0}'", FormatChar))); } } try { if (ParseState.Unindent.Contains((uint)InstructionPosition)) { ParseState.Indent--; } switch (Opcode.OpcodeName) { case "JUMP_ALWAYS": ParseState.Indent--; break; } return(new Instruction() { Position = (uint)InstructionPosition, Opcode = Opcode, Parameters = Params.ToArray(), Indent = ParseState.Indent, }); } finally { switch (Opcode.OpcodeName) { //case "FUNCTION_DEF": case "JUMP_IF": ParseState.Unindent.Add(((LabelReference)(Params.ToArray()[3])).Offset); ParseState.Indent++; break; case "JUMP_ALWAYS": ParseState.Unindent.Add(((LabelReference)(Params.ToArray()[0])).Offset); ParseState.Indent += 2; break; } } }