/* * public class X86TextSpan * { * public X86TextSpan(int start, int end) * { * Start = start; * End = end; * } * * public int Start { get; set; } * public int End { get; set; } * } * * * public class X86Instruction : X86TextSpan * { * public X86Instruction(int start, int end, string name, AsmHighlighterToken type) : base(start, end) * { * Name = name; * Type = type; * } * * public string Name { get; set; } * public AsmHighlighterToken Type { get; set; } * } * * public class X86Code * { * public X86Instruction Instruction { get; set; } * * } * * public X86Code Parse(Scanner lexer, string codeToParse) * { * lexer.SetSource(codeToParse, 0); * int state = 0; * int start, end; * * AsmHighlighterToken token = (AsmHighlighterToken)lexer.GetNext(ref state, out start, out end); * List<EditSpan> changes = new List<EditSpan>(); * while (token != AsmHighlighterToken.EOF) * { * bool isToStrip = false; * string stripReplace = ""; * string tokenStr = codeToParse.Substring(start, end - start + 1).ToLower(); * switch (token) * { * case AsmHighlighterToken.INSTRUCTION: * if (tokenStr == "call" || tokenStr.StartsWith("j")) * { * string restOfLine = codeToParse.Substring(end + 1, codeToParse.Length - (end + 1)).Trim(); * // Default call|jmp dword * if (!restOfLine.StartsWith("dword") && !restOfLine.StartsWith("short")) * { * isToStrip = true; * stripReplace = tokenStr + " dword"; * } * } * break; * case AsmHighlighterToken.LEFT_SQUARE_BRACKET: * * * break; * case AsmHighlighterToken.RIGHT_SQUARE_BRACKET: * * * break; * case AsmHighlighterToken.REGISTER: * if (tokenStr.StartsWith("st(")) * { * tokenStr = tokenStr.Replace("(", ""); * tokenStr = tokenStr.Replace(")", ""); * isToStrip = true; * stripReplace = tokenStr; * } * break; * case AsmHighlighterToken.DIRECTIVE: * // strip register * if (tokenStr == "ptr") * { * isToStrip = true; * stripReplace = ""; * } * break; * * case AsmHighlighterToken.IDENTIFIER: * // Convert all identifiers to 0 in order to be able to compile the code * isToStrip = true; * stripReplace = "125125"; * break; * } * if (isToStrip) * { * TextSpan editTextSpan = new TextSpan(); * editTextSpan.iStartLine = 0; * editTextSpan.iEndLine = 0; * editTextSpan.iStartIndex = start; * editTextSpan.iEndIndex = end + 1; * * changes.Add(new EditSpan(editTextSpan, stripReplace)); * } * token = (AsmHighlighterToken)lexer.GetNext(ref state, out start, out end); * } * return null; * } */ public static string ConvertToFasm(Scanner lexer, string codeToFormat, Dictionary <string, string> defines) { lexer.SetSource(codeToFormat, 0); int state = 0; int start, end; bool isInBracket = false; int countRegisterInBracket = 0; AsmHighlighterToken token = (AsmHighlighterToken)lexer.GetNext(ref state, out start, out end); List <EditSpan> changes = new List <EditSpan>(); while (token != AsmHighlighterToken.EOF) { bool isToStrip = false; string stripReplace = ""; string tokenStr = codeToFormat.Substring(start, end - start + 1).ToLower(); switch (token) { case AsmHighlighterToken.INSTRUCTION: if (tokenStr == "call" || tokenStr.StartsWith("j")) { string restOfLine = codeToFormat.Substring(end + 1, codeToFormat.Length - (end + 1)).Trim(); // Set default call|jxx to dword if (!restOfLine.StartsWith("dword") && !restOfLine.StartsWith("short") && !restOfLine.StartsWith("near") && !restOfLine.StartsWith("far")) { isToStrip = true; stripReplace = tokenStr + " dword"; } } break; case AsmHighlighterToken.LEFT_SQUARE_BRACKET: isInBracket = true; break; case AsmHighlighterToken.RIGHT_SQUARE_BRACKET: isInBracket = false; countRegisterInBracket = 0; break; case AsmHighlighterToken.REGISTER: case AsmHighlighterToken.REGISTER_FPU: case AsmHighlighterToken.REGISTER_MMXSSE: if (isInBracket) { countRegisterInBracket++; } // Convert st(#) register to st# if (token == AsmHighlighterToken.REGISTER_FPU) { tokenStr = tokenStr.Replace("(", ""); tokenStr = tokenStr.Replace(")", ""); isToStrip = true; stripReplace = tokenStr; } break; case AsmHighlighterToken.DIRECTIVE: // strip register if (tokenStr == "ptr") { isToStrip = true; stripReplace = ""; } break; case AsmHighlighterToken.IDENTIFIER: isToStrip = true; stripReplace = (defines.ContainsKey(tokenStr)) ? defines[tokenStr] : "4"; if (isInBracket) { if ((lexer.AsmHighlighterTokenProvider.GetTokenFromIdentifier(stripReplace) & AsmHighlighterToken.IS_REGISTER) != 0) { countRegisterInBracket++; } else if (stripReplace == "4") { // No register before 1st identifier if (countRegisterInBracket == 0) { // Fake dword adress if we have mov [IDENTIFIER + ....] stripReplace = "123123"; } } } break; } if (isToStrip) { TextSpan editTextSpan = new TextSpan(); editTextSpan.iStartLine = 0; editTextSpan.iEndLine = 0; editTextSpan.iStartIndex = start; editTextSpan.iEndIndex = end + 1; changes.Add(new EditSpan(editTextSpan, stripReplace)); } token = (AsmHighlighterToken)lexer.GetNext(ref state, out start, out end); } for (int i = changes.Count - 1; i >= 0; i--) { EditSpan editSpan = changes[i]; codeToFormat = codeToFormat.Substring(0, editSpan.Span.iStartIndex) + editSpan.Text + codeToFormat.Substring(editSpan.Span.iEndIndex, codeToFormat.Length - editSpan.Span.iEndIndex); } // Force the FASM code to 32 bit codeToFormat = "use32\r\n" + codeToFormat; return(codeToFormat); }
public int ComputeDataTipOnContext(IVsTextLines textLines, int line, int col, ref TextSpan span, out string tipText) { int result = VSConstants.E_NOTIMPL; tipText = ""; span.iStartLine = line; span.iStartIndex = col; span.iEndLine = line; span.iEndIndex = col; if (textLines != null) { // Parse tokens and search for the token below the selection AsmHighlighterScanner scanner = AsmHighlighterScannerFactory.GetScanner(textLines); string lineOfCode; List <TokenInfo> tokenInfoList = scanner.ParseLine(textLines, line, int.MaxValue, out lineOfCode); TokenInfo selectedTokenInfo = null; foreach (TokenInfo info in tokenInfoList) { if (col >= info.StartIndex && col <= info.EndIndex) { selectedTokenInfo = info; break; } } // If a valid token was found, handle it if (selectedTokenInfo != null) { AsmHighlighterToken token = (AsmHighlighterToken)selectedTokenInfo.Token; // Display only tip for REGISTER or IDENTIFIER if ((token & AsmHighlighterToken.IS_REGISTER) != 0 || (token & AsmHighlighterToken.IS_NUMBER) != 0 || token == AsmHighlighterToken.IDENTIFIER) { result = VSConstants.S_OK; tipText = lineOfCode.Substring(selectedTokenInfo.StartIndex, selectedTokenInfo.EndIndex - selectedTokenInfo.StartIndex + 1); if ((token & AsmHighlighterToken.IS_REGISTER) != 0) { tipText = tipText.ToLower(); if (token == AsmHighlighterToken.REGISTER_FPU) { tipText = tipText.Replace("(", ""); tipText = tipText.Replace(")", ""); } } span.iStartIndex = selectedTokenInfo.StartIndex; span.iEndIndex = selectedTokenInfo.EndIndex + 1; // If in debugging mode, display the value // (This is a workaround instead of going through the Debugger.ExpressionEvaluator long way...) // TODO: ExpressionEvaluator is not working, this is a workaround to display values if (IsDebugging() && (((token & AsmHighlighterToken.IS_REGISTER) != 0) || token == AsmHighlighterToken.IDENTIFIER)) { Expression expression = vs.Debugger.GetExpression(tipText, true, 1000); string valueStr = ""; // Make a friendly printable version for float/double and numbers try { if (expression.Type.Contains("double")) { double value = double.Parse(expression.Value); valueStr = string.Format("{0:r}", value); } else { long value = long.Parse(expression.Value); valueStr = string.Format("0x{0:X8}", value); } } catch { } // Print a printable version only if it's valid if (string.IsNullOrEmpty(valueStr)) { tipText = string.Format("{0} = {1}", tipText, expression.Value); } else { tipText = string.Format("{0} = {1} = {2}", tipText, valueStr, expression.Value); } } } } } return(result); }
public bool ScanTokenAndProvideInfoAboutIt(TokenInfo tokenInfo, ref int state) { int start, end; AsmHighlighterToken token = (AsmHighlighterToken)lex.GetNext(ref state, out start, out end); // !EOL and !EOF if (token == AsmHighlighterToken.EOF) { return(false); } tokenInfo.StartIndex = start; tokenInfo.EndIndex = end; switch (token) { case AsmHighlighterToken.INSTRUCTION: tokenInfo.Color = (TokenColor)AsmTokenColor.Keyword; tokenInfo.Type = TokenType.Keyword; break; case AsmHighlighterToken.COMMENT_LINE: tokenInfo.Color = (TokenColor)AsmTokenColor.Comment; tokenInfo.Type = TokenType.LineComment; break; case AsmHighlighterToken.NUMBER: case AsmHighlighterToken.FLOAT: tokenInfo.Color = (TokenColor)AsmTokenColor.Number; tokenInfo.Type = TokenType.Literal; break; case AsmHighlighterToken.STRING_LITERAL: tokenInfo.Color = (TokenColor)AsmTokenColor.String; tokenInfo.Type = TokenType.String; break; case AsmHighlighterToken.REGISTER: case AsmHighlighterToken.REGISTER_FPU: case AsmHighlighterToken.REGISTER_MMXSSE: case AsmHighlighterToken.REGISTER_AVX: case AsmHighlighterToken.REGISTER_AVX512: tokenInfo.Color = (TokenColor)AsmTokenColor.AsmRegister; tokenInfo.Type = TokenType.Identifier; break; case AsmHighlighterToken.FPUPROCESSOR: tokenInfo.Color = (TokenColor)AsmTokenColor.AsmFpuInstruction; tokenInfo.Type = TokenType.Identifier; break; case AsmHighlighterToken.DIRECTIVE: tokenInfo.Color = (TokenColor)AsmTokenColor.AsmDirective; tokenInfo.Type = TokenType.Keyword; break; case AsmHighlighterToken.SSE: case AsmHighlighterToken.FMA3: case AsmHighlighterToken.AVX: case AsmHighlighterToken.AVX2: case AsmHighlighterToken.AVX512F: tokenInfo.Color = (TokenColor)AsmTokenColor.AsmSimdInstruction; tokenInfo.Type = TokenType.Keyword; break; default: tokenInfo.Color = TokenColor.Text; tokenInfo.Type = TokenType.Text; break; } return(true); }
public bool ScanTokenAndProvideInfoAboutIt(TokenInfo tokenInfo, ref int state) { int start, end; AsmHighlighterToken token = (AsmHighlighterToken)lex.GetNext(ref state, out start, out end); // !EOL and !EOF if (token == AsmHighlighterToken.EOF) { return(false); } tokenInfo.StartIndex = start; tokenInfo.EndIndex = end; switch (token) { case AsmHighlighterToken.INSTRUCTION: tokenInfo.Color = TokenColor.Keyword; tokenInfo.Type = TokenType.Keyword; break; case AsmHighlighterToken.COMMENT_LINE: tokenInfo.Color = TokenColor.Comment; tokenInfo.Type = TokenType.LineComment; break; case AsmHighlighterToken.NUMBER: case AsmHighlighterToken.FLOAT: tokenInfo.Color = TokenColor.Number; tokenInfo.Type = TokenType.Literal; break; case AsmHighlighterToken.STRING_LITERAL: tokenInfo.Color = TokenColor.String; tokenInfo.Type = TokenType.String; break; case AsmHighlighterToken.REGISTER: case AsmHighlighterToken.REGISTER_FPU: case AsmHighlighterToken.REGISTER_MMXSSE: case AsmHighlighterToken.REGISTER_AVX: case AsmHighlighterToken.REGISTER_AVX512: // hugly. TODO generate a AsmHighlighterTokenColor to keep tracks of 6-7-8 TokenColors tokenInfo.Color = TokenColor.String; tokenInfo.Type = TokenType.Identifier; break; case AsmHighlighterToken.FPUPROCESSOR: tokenInfo.Color = TokenColor.Identifier; tokenInfo.Type = TokenType.Identifier; break; case AsmHighlighterToken.DIRECTIVE: tokenInfo.Color = TokenColor.Keyword; tokenInfo.Type = TokenType.Keyword; break; case AsmHighlighterToken.SIMDPROCESSOR: case AsmHighlighterToken.SSE4: case AsmHighlighterToken.AVX2: case AsmHighlighterToken.FMA: tokenInfo.Color = TokenColor.Keyword; tokenInfo.Type = TokenType.Keyword; break; default: tokenInfo.Color = TokenColor.Text; tokenInfo.Type = TokenType.Text; break; } return(true); }
public static List <EditSpan> ReformatCode(IVsTextLines pBuffer, TextSpan span, int tabSize) { string filePath = FilePathUtilities.GetFilePath(pBuffer); // Return dynamic scanner based on file extension List <EditSpan> changeList = new List <EditSpan>(); string codeToFormat; int endOfFirstLineIndex; // Get 1st line and parse custom define pBuffer.GetLengthOfLine(0, out endOfFirstLineIndex); pBuffer.GetLineText(0, 0, 0, endOfFirstLineIndex, out codeToFormat); Dictionary <string, string> defines = ParseDefineLine(codeToFormat); AsmHighlighterScanner scanner = AsmHighlighterScannerFactory.GetScanner(filePath); Scanner lexer = scanner.Lexer; // Iterate on each line of the selection to format for (int line = span.iStartLine; line <= span.iEndLine; line++) { int lineLength; pBuffer.GetLengthOfLine(line, out lineLength); pBuffer.GetLineText(line, 0, line, lineLength, out codeToFormat); string codeToAssemble = ConvertToFasm(lexer, codeToFormat, defines); lexer.SetSource(codeToFormat, 0); int state = 0; int start, end; bool instructionFound = false, commentFound = false; int commentStart = 0; AsmHighlighterToken token = (AsmHighlighterToken)lexer.GetNext(ref state, out start, out end); while (token != AsmHighlighterToken.EOF) { switch (token) { case AsmHighlighterToken.INSTRUCTION: case AsmHighlighterToken.FPUPROCESSOR: case AsmHighlighterToken.SIMDPROCESSOR: instructionFound = true; break; case AsmHighlighterToken.COMMENT_LINE: if (!commentFound) { commentFound = true; commentStart = start; } break; } if (instructionFound && commentFound) { byte[] buffer = null; try { buffer = ManagedFasm.Assemble(codeToAssemble); } catch (Exception) { // ignored } if (buffer != null) { } TextSpan editTextSpan = new TextSpan(); editTextSpan.iStartLine = line; editTextSpan.iEndLine = line; editTextSpan.iStartIndex = commentStart; editTextSpan.iEndIndex = commentStart + 1; if ((codeToFormat.Length - commentStart) > 2 && codeToFormat.Substring(commentStart, 2) == ";#") { editTextSpan.iEndIndex = editTextSpan.iEndIndex + 2; } string text = ";#" + ((buffer == null) ? "?" : string.Format("{0:X}", buffer.Length)); changeList.Add(new EditSpan(editTextSpan, text)); break; } token = (AsmHighlighterToken)lexer.GetNext(ref state, out start, out end); } } return(changeList); }