static IParser <byte, InstructionParseState, InstructionParseState> ParseStringLiteral() { return(FunctionalParser.Create( (IParseState <byte, InstructionParseState> input) => { if (input == null) { return null; } var results = input.Result; var peFile = results.MethodDefinition.Module.PEFile; var size = (int)StreamID.UserStrings.IndexSize(peFile); if (input.RemainingInput.Count < size) { return null; } uint index; if (size == 2) { index = input.RemainingInput.ReadLittleEndianUShort(); } else { index = input.RemainingInput.ReadLittleEndianUInt(); } var operand = peFile.ReadUserString(index); results.Operand = operand; results.PrettyPrint = results.PrettyPrint.Then(b => b.AppendFormat(" {0}", operand.Escape())); return ParseState.Create(input.ConsumedInput.Expand(size), input.RemainingInput.SubList(size), results); }, (byte)0 )); }
static IParser <byte, InstructionParseState, InstructionParseState> ParseFixedSizeOperand <T>( Func <IParseState <byte, InstructionParseState>, T> f, int bytesNeeded, Action <T, StringBuilder> prettyPrint, Func <T, bool> predicate ) { return(FunctionalParser.Create( (IParseState <byte, InstructionParseState> input) => { if (input == null || input.RemainingInput.Count < bytesNeeded) { return null; } var result = input.Result; var operand = f(input); if (!predicate(operand)) { return null; } result.Operand = operand; result.PrettyPrint = result.PrettyPrint.Then(b => prettyPrint(operand, b)); return ParseState.Create(input.ConsumedInput.Expand(bytesNeeded), input.RemainingInput.SubList(bytesNeeded), result); }, (byte)0 )); }
static IParser <byte, InstructionParseState, InstructionParseState> ParseSwitchTable() { return(FunctionalParser.Create( (IParseState <byte, InstructionParseState> input) => { if (input == null || input.RemainingInput.Count < 4) { return null; } var n = checked ((int)input.RemainingInput.ReadLittleEndianUInt()); if (input.RemainingInput.Count < checked ((n + 1) * 4)) { return null; } var results = input.Result; var operand = GetSwitchTargets(input, n); results.Operand = operand; var targets = Enumerable.Range(1, n).Select(x => input.RemainingInput.SubList(x * 4).ReadLittleEndianInt()); results.PrettyPrint.Then(b => targets.Print(b, ",", " ", "")); return ParseState.Create( input.ConsumedInput.Expand((n + 1) * 4), input.RemainingInput.SubList((n + 1) * 4), results ); }, (byte)0 )); }
static IParser <byte, InstructionParseState, InstructionParseState> ID() { return(FunctionalParser.Create( (IParseState <byte, InstructionParseState> input) => input, (byte)0 )); }
static IParser <byte, InstructionParseState, InstructionParseState> Consume(byte b) { return(FunctionalParser.Create( (IParseState <byte, InstructionParseState> input) => { if (input == null || input.RemainingInput.Count == 0 || input.RemainingInput[0] != b) { return null; } return ParseState.Create(input.ConsumedInput.Expand(1), input.RemainingInput.SubList(1), input.Result); }, b )); }
static IParser <byte, InstructionParseState, InstructionParseState> SetOperand(Object operand) { return(FunctionalParser.Create( (IParseState <byte, InstructionParseState> input) => { if (input == null) { return null; } var result = input.Result; result.Operand = operand; return ParseState.Create(input.ConsumedInput, input.RemainingInput, result); }, (byte)0 )); }
static IParser <byte, InstructionParseState, InstructionParseState> SetOpcode(Opcode opcode, String pretty) { return(FunctionalParser.Create( (IParseState <byte, InstructionParseState> input) => { if (input == null) { return null; } var result = input.Result; result.Opcode = opcode; result.PrettyPrint = builder => builder.Append(pretty); return ParseState.Create(input.ConsumedInput, input.RemainingInput, result); }, (byte)0 )); }
static IParser <byte, InstructionParseState, InstructionParseState> ParseNestedInstruction() { return(FunctionalParser.Create( (IParseState <byte, InstructionParseState> input) => { var output = s_parser.Parse(input); if (output == null) { return null; } var result = input.AssumeNotNull().Result; result.NestedInstruction = output.Result; result.PrettyPrint = result.PrettyPrint.Then(b => b.Append(" ")).Then( b => output.Result.ToString(b) ); return ParseState.Create(output.ConsumedInput, output.RemainingInput, result); }, (byte)0 )); }