public virtual void ToRichText(RichTextBuilder builder) { string format; if (OpcodeFormats.TryGetValue(Opcode, out format)) { for (int index = 0; index < format.Length; index++) { if (format[index] == '{') { if (format[index + 1] == '{') { index++; builder.Append('{'); } else { int end; for (end = ++index; format[end] != '}'; end++) { ; } int operandIndex = int.Parse(format.Substring(index, end - index)); ScriptOperand operand = GetOperand(operandIndex); operand.ToRichText(builder); index = end; } } else { builder.Append(format[index]); } } } else { if (IsOpcodeDefined) { builder.Append(Opcode.ToString()); } else { builder.ForegroundColor = Color.Red; builder.AppendFormat("{0:X2}", (int)Opcode); builder.ForegroundColor = Color.Black; } foreach (ScriptOperand operand in Operands) { builder.Append(" "); operand.ToRichText(builder); } } }
public static ScriptInstruction Read(Script script, BinaryReader reader) { long offset = reader.BaseStream.Position; ScriptOperand opcodeToken = new ScriptOperand(reader, ScriptArgument.Opcode); if (!opcodeToken.IsOpcode) { return(new Invalid(script, offset, opcodeToken)); } ScriptOpcode opcode = opcodeToken.GetOpcode(); switch (opcode) { case ScriptOpcode.Call: return(new Call(script, offset, reader)); case ScriptOpcode.Switch: return(new Switch(script, offset, reader)); case ScriptOpcode.If: return(new If(script, offset, reader)); default: return(new ScriptInstruction(script, offset, reader, opcode)); } }
public Invalid(Script script, long offset, ScriptOperand invalidToken) : base(script, offset, ScriptOpcode.Invalid) { InvalidToken = invalidToken; invalidToken.Instruction = this; }
protected bool ReadOperand(BinaryReader reader, string operands, ref int operandIndex, ScriptArgument operandCode) { long offset = reader.BaseStream.Position; ScriptOperand token = new ScriptOperand(reader, operandCode); token.Instruction = this; int outputIndex = OperandsMutable.Count; OperandsMutable.Add(token); switch (operandCode) { case ScriptArgument.Address: case ScriptArgument.Value: case ScriptArgument.ValueOrVariable: case ScriptArgument.String: case ScriptArgument.Variable: case ScriptArgument.Literal: case ScriptArgument.UnknownVariable: case ScriptArgument.Comparison: token.IsValid = token.MatchTypeCode(operandCode); break; case ScriptArgument.Array: ScriptArgument arrayCountType = (ScriptArgument)operands[++operandIndex]; ScriptArgument arrayType = (ScriptArgument)operands[++operandIndex]; if (IsCompoundOperandCode(arrayCountType) || IsCompoundOperandCode(arrayType)) { throw new InvalidOperationException(); } token.IsValid = token.MatchTypeCode(arrayCountType); if (!token.IsValid) { OperandsMutable[outputIndex] = token; return(false); } for (int index = 0; index < token.AsValue; index++) { if (!ReadOperand(reader, operands, ref operandIndex, arrayType)) { return(false); } } break; case ScriptArgument.Optional: operandCode = (ScriptArgument)operands[++operandIndex]; if (!token.MatchTypeCode(operandCode)) { reader.BaseStream.Position = offset; OperandsMutable.RemoveAt(outputIndex); return(true); } break; default: throw new InvalidOperationException("Invalid operand type code '" + operandCode + "'."); } OperandsMutable[outputIndex] = token; return(true); }
int?GetIntegerOperand(int index) { ScriptOperand operand = GetOperand(index); return(operand.IsValid && operand.IsValue ? (int?)operand.AsValue : null); }
protected bool ReadOperand(BinaryReader reader, string operands, ref int operandIndex, ScriptArgument operandCode) { long offset = reader.BaseStream.Position; ScriptOperand token = new ScriptOperand(reader, operandCode); token.Instruction = this; int outputIndex = OperandsMutable.Count; OperandsMutable.Add(token); switch (operandCode) { case ScriptArgument.Address: case ScriptArgument.Value: case ScriptArgument.ValueOrVariable: case ScriptArgument.String: case ScriptArgument.Variable: case ScriptArgument.Literal: case ScriptArgument.UnknownVariable: case ScriptArgument.Comparison: token.IsValid = token.MatchTypeCode(operandCode); break; case ScriptArgument.Array: ScriptArgument arrayCountType = (ScriptArgument)operands[++operandIndex]; ScriptArgument arrayType = (ScriptArgument)operands[++operandIndex]; if (IsCompoundOperandCode(arrayCountType) || IsCompoundOperandCode(arrayType)) throw new InvalidOperationException(); token.IsValid = token.MatchTypeCode(arrayCountType); if (!token.IsValid) { OperandsMutable[outputIndex] = token; return false; } for (int index = 0; index < token.AsValue; index++) if (!ReadOperand(reader, operands, ref operandIndex, arrayType)) return false; break; case ScriptArgument.Optional: operandCode = (ScriptArgument)operands[++operandIndex]; if (!token.MatchTypeCode(operandCode)) { reader.BaseStream.Position = offset; OperandsMutable.RemoveAt(outputIndex); return true; } break; default: throw new InvalidOperationException("Invalid operand type code '" + operandCode + "'."); } OperandsMutable[outputIndex] = token; return true; }
public static ScriptInstruction Read(Script script, BinaryReader reader) { long offset = reader.BaseStream.Position; ScriptOperand opcodeToken = new ScriptOperand(reader, ScriptArgument.Opcode); if (!opcodeToken.IsOpcode) return new Invalid(script, offset, opcodeToken); ScriptOpcode opcode = opcodeToken.GetOpcode(); switch (opcode) { case ScriptOpcode.Call: return new Call(script, offset, reader); case ScriptOpcode.Switch: return new Switch(script, offset, reader); case ScriptOpcode.If: return new If(script, offset, reader); default: return new ScriptInstruction(script, offset, reader, opcode); } }