private static void DisplayToken(StringBuilder output, AsmToken asmToken) { if (asmToken.LeadingWhiteSpace != null) { DisplayToken(output, asmToken.LeadingWhiteSpace); } output.Append("<span class=\"" + GetClassFromTokenType(asmToken.Type) + "\">"); output.Append(asmToken.Text); output.Append("</span>"); }
public AsmToken(string asmLine, AsmToken leadingWhitespaceToken, AsmTokenType type, int startIndex, int endIndex, object value) { this.asmLine = asmLine; this.LeadingWhiteSpace = leadingWhitespaceToken; Type = type; StartIndex = startIndex; EndIndex = endIndex; Value = value; }
public AsmToken(string asmLine, AsmToken leadingWhitespaceToken, AsmTokenType type, int startIndex, int endIndex) : this(asmLine, leadingWhitespaceToken, type, startIndex, endIndex, null) { }
private AsmToken FindNextToken() { int startIndex = nextIndex; char startChar = GetNextChar(); AsmToken leadingWhitespaceToken = null; if (IsWhitespace(startChar)) { AsmTokenType type = AsmTokenType.WHITESPACE; for (char c = PeekNextChar(); IsWhitespace(c); c = PeekNextChar()) { GetNextChar(); } int endIndex = nextIndex; leadingWhitespaceToken = new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); // Start next token startIndex = nextIndex; startChar = GetNextChar(); } switch (startChar) { case ':': AsmTokenType type = AsmTokenType.COLON; int endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); case ',': type = AsmTokenType.COMMA; endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); case '(': type = AsmTokenType.OPENINGPAR; endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); case ')': type = AsmTokenType.CLOSINGPAR; endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); case '+': type = AsmTokenType.PLUS; endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); case '-': type = AsmTokenType.MINUS; endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); case '*': type = AsmTokenType.MULTIPLY; endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); case '[': type = AsmTokenType.OPENINGBRA; endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); case ']': type = AsmTokenType.CLOSINGBRA; endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); case '$': char nc = PeekNextChar(); if(!IsHexaDigit(nc)) { type = AsmTokenType.DOLLAR; endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); } else { type = AsmTokenType.NUMBER; int valStartIndex = nextIndex; for (char c = PeekNextChar(); c != (char)0 && IsHexaDigit(c); c = PeekNextChar()) { GetNextChar(); } endIndex = nextIndex; int intValue = Convert.ToInt32(asmLine.Substring(valStartIndex, endIndex - valStartIndex), 16); return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex, intValue); } case ';': type = AsmTokenType.COMMENT; while(GetNextChar() != 0) { } endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex, asmLine.Substring(startIndex + 1, endIndex - startIndex - 1).Trim()); case '"': type = AsmTokenType.STRING; int valueStartIndex = nextIndex; char previousChar = (char)0; StringBuilder sbValue; ReadStringToken('"', startIndex, valueStartIndex, previousChar, out endIndex, out sbValue); return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex, sbValue.ToString()); case '\'': type = AsmTokenType.NUMBER; valueStartIndex = nextIndex; char chr = GetNextChar(); if(chr == '\\') { chr = GetNextChar(); chr = GetCharValueFromEscapeChar(chr); } if(GetNextChar() != '\'') { // Then switch to string token type = AsmTokenType.STRING; previousChar = chr; ReadStringToken('\'', startIndex, valueStartIndex, previousChar, out endIndex, out sbValue); return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex, sbValue.ToString()); } endIndex = nextIndex; int asciiValue = (byte)chr; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex, asciiValue); case '%': type = AsmTokenType.NUMBER; valueStartIndex = nextIndex; for (char c = PeekNextChar(); c != (char)0 && (c == '0' || c == '1'); c = PeekNextChar()) { GetNextChar(); } endIndex = nextIndex; int binValue = Convert.ToByte(asmLine.Substring(valueStartIndex, endIndex - valueStartIndex), 2); return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex, binValue); case (char)0: type = AsmTokenType.ENDOFLINE; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, startIndex); default: // Special case 1 : 0-7 char is ambiguous, it can be a BIT or a NUMBER, but it can be a BIT only if previous token is OPCODE = BIT, RES, SET if(startChar >= 48 && startChar <= 55 && currentToken.Type == AsmTokenType.OPCODE && (String.Compare(currentToken.Text, "BIT", stringComparisonMode) == 0 || String.Compare(currentToken.Text, "RES", stringComparisonMode) == 0 || String.Compare(currentToken.Text, "SET", stringComparisonMode) == 0 )) { type = AsmTokenType.BIT; endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex, startChar - 48); } // Special case 2 : 0-2 char is ambiguous, it can be an INTERRUPTMODE or a NUMBER, but it can be an INTERRUPTMODE only if previous token is OPCODE = IM else if(startChar >= 48 && startChar <= 50 && currentToken.Type == AsmTokenType.OPCODE && String.Compare(currentToken.Text, "IM", stringComparisonMode) == 0 ) { type = AsmTokenType.INTERRUPTMODE; endIndex = nextIndex; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex, startChar - 48); } else if(IsFirstSymbolChar(startChar)) { for (char c = PeekNextChar(); c != (char)0 && IsSymbolChar(c); c = PeekNextChar()) { GetNextChar(); } endIndex = nextIndex; string symbol = asmLine.Substring(startIndex, endIndex - startIndex); // Special case 3 : ' is not a valid symbol char, but AF' is a valid register name if(String.Compare(symbol, "AF", stringComparisonMode) == 0 && PeekNextChar() == '\'') { GetNextChar(); endIndex = nextIndex; symbol = "AF'"; } // Special case 4 : C symbol is ambiguous, it can be a flag condition or a register, but it can be a flag only if previous token is OPCODE = CALL, JP, JR, RET if(String.Compare(symbol, "C", stringComparisonMode) == 0 && currentToken.Type == AsmTokenType.OPCODE && (String.Compare(currentToken.Text, "CALL", stringComparisonMode) == 0 || String.Compare(currentToken.Text, "JP", stringComparisonMode) == 0 || String.Compare(currentToken.Text, "JR", stringComparisonMode) == 0 || String.Compare(currentToken.Text, "RET", stringComparisonMode) == 0 )) { type = AsmTokenType.FLAGCONDITION; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); } else if(OPCODES.Contains<string>(symbol, stringComparer)) { type = AsmTokenType.OPCODE; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); } else if (REGISTERS8.Contains<string>(symbol, stringComparer)) { type = AsmTokenType.REGISTER; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); } else if (REGISTERS16.Contains<string>(symbol, stringComparer)) { type = AsmTokenType.REGISTER16; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); } else if (FLAGS.Contains<string>(symbol, stringComparer)) { type = AsmTokenType.FLAGS; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); } else if(FLAGCONDITIONS.Contains<string>(symbol, stringComparer)) { type = AsmTokenType.FLAGCONDITION; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); } else if(DIRECTIVES.Contains<string>(symbol, stringComparer)) { type = AsmTokenType.DIRECTIVE; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); } // Special case 5 : an hexadecimal number is also a valid symbol else if(hexaNumberRegex.IsMatch(symbol)) { type = AsmTokenType.NUMBER; Match hexaMatch = hexaNumberRegex.Match(symbol); string numberString = hexaMatch.Groups[1].Value; int intValue = 0; if (numberString.Length <= 2) { intValue = Convert.ToByte(numberString, 16); } else { intValue = Convert.ToUInt16(numberString, 16); } return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex, intValue); } else { type = AsmTokenType.SYMBOL; return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, endIndex); } } else if(IsDigit(startChar)) { type = AsmTokenType.NUMBER; for (char c = PeekNextChar(); c != (char)0 && IsHexaDigit(c); c = PeekNextChar()) { GetNextChar(); } switch (PeekNextChar()) { case 'O': case 'Q': case 'H': case 'o': case 'q': case 'h': GetNextChar(); break; } int nbEndIndex = nextIndex; string numberString = asmLine.Substring(startIndex, nbEndIndex - startIndex); int intValue = 0; if(hexaNumberRegex.IsMatch(numberString)) { Match hexaMatch = hexaNumberRegex.Match(numberString); numberString = hexaMatch.Groups[1].Value; if (numberString.Length <= 2) { intValue = Convert.ToByte(numberString, 16); } else { intValue = Convert.ToUInt16(numberString, 16); } } else if (decimalNumberRegex.IsMatch(numberString)) { Match decimalMatch = decimalNumberRegex.Match(numberString); numberString = decimalMatch.Groups[1].Value; intValue = UInt16.Parse(numberString); } else if (binaryNumberRegex.IsMatch(numberString)) { Match binMatch = binaryNumberRegex.Match(numberString); numberString = binMatch.Groups[1].Value; if (numberString.Length <= 8) { intValue = Convert.ToByte(numberString, 2); } else { intValue = Convert.ToUInt16(numberString, 2); } } else if (octalNumberRegex.IsMatch(numberString)) { Match octalMatch = octalNumberRegex.Match(numberString); numberString = octalMatch.Groups[1].Value; intValue = Convert.ToUInt16(numberString , 8); } else { throw new Exception(String.Format("Line {0} : Invalid number format {1} at column {2}", lineNumber, numberString, startIndex)); } return new AsmToken(asmLine, leadingWhitespaceToken, type, startIndex, nbEndIndex, intValue); } else { throw new Exception(String.Format("Line {0} : Unexpected char {1} at column {2}", lineNumber, startChar, startIndex)); } } }
public AsmToken PeekNextToken() { if (nextToken == null) { nextToken = FindNextToken(); } return nextToken; }
public AsmToken GetNextToken() { if (nextToken != null) { currentToken = nextToken; nextToken = null; } else { currentToken = FindNextToken(); } AllTokens.Add(currentToken); if(buildTokenList) { partialTokenList.Add(currentToken); } return currentToken; }