void Push(char ch) { if (readPreprocessorExpression) { wordBuf.Append(ch); } if (inside.HasFlag(Inside.VerbatimString) && pc == '"' && ch != '"') { inside &= ~Inside.String; } switch (ch) { case '#': if (IsLineStart) { inside = Inside.PreProcessor; } break; case '/': if (IsInStringOrChar || IsInPreProcessorComment) { break; } if (pc == '/') { if (inside.HasFlag(Inside.Comment)) { inside |= Inside.DocComment; } else { inside |= Inside.Comment; } } break; case '*': if (IsInStringOrChar || IsInComment || IsInPreProcessorComment) { break; } if (pc == '/') { inside |= Inside.MultiLineComment; } break; case '\t': var nextTabStop = (col - 1 + textEditorOptions.IndentSize) / textEditorOptions.IndentSize; col = 1 + nextTabStop * textEditorOptions.IndentSize; return; case '\r': if (readPreprocessorExpression) { if (!eval(wordBuf.ToString())) { inside |= Inside.PreProcessorComment; } } inside &= ~(Inside.Comment | Inside.String | Inside.CharLiteral | Inside.PreProcessor); CheckKeyword(wordBuf.ToString()); wordBuf.Length = 0; if (addContinuation) { indent.Push(IndentType.Continuation); } thisLineindent = indent.Clone(); addContinuation = false; IsLineStart = true; readPreprocessorExpression = false; col = 1; line++; break; case '\n': if (pc == '\r') { break; } goto case '\r'; case '"': if (IsInComment || IsInPreProcessorComment) { break; } if (inside.HasFlag(Inside.String)) { if (pc != '\\') { inside &= ~Inside.String; } break; } if (pc == '@') { inside |= Inside.VerbatimString; } else { inside |= Inside.String; } break; case '<': case '[': case '(': if (IsInComment || IsInStringOrChar || IsInPreProcessorComment) { break; } parenStack.Push(new TextLocation(line, col)); popNextParenBlock = true; indent.Push(IndentType.Block); break; case '>': case ']': case ')': if (IsInComment || IsInStringOrChar || IsInPreProcessorComment) { break; } if (popNextParenBlock) { parenStack.Pop(); } indent.Pop(); indent.ExtraSpaces = 0; break; case ',': if (IsInComment || IsInStringOrChar || IsInPreProcessorComment) { break; } if (parenStack.Count > 0 && parenStack.Peek().Line == line) { indent.Pop(); popNextParenBlock = false; indent.ExtraSpaces = parenStack.Peek().Column - 1 - thisLineindent.CurIndent; } break; case '{': if (IsInComment || IsInStringOrChar || IsInPreProcessorComment) { break; } currentBody = nextBody; if (indent.Count > 0 && indent.Peek() == IndentType.Continuation) { indent.Pop(); } addContinuation = false; AddIndentation(currentBody); break; case '}': if (IsInComment || IsInStringOrChar || IsInPreProcessorComment) { break; } indent.Pop(); if (indent.Count > 0 && indent.Peek() == IndentType.Continuation) { indent.Pop(); } break; case ';': if (IsInComment || IsInStringOrChar || IsInPreProcessorComment) { break; } if (indent.Count > 0 && indent.Peek() == IndentType.Continuation) { indent.Pop(); } break; case '\'': if (IsInComment || inside.HasFlag(Inside.String) || IsInPreProcessorComment) { break; } if (inside.HasFlag(Inside.CharLiteral)) { if (pc != '\\') { inside &= ~Inside.CharLiteral; } } else { inside &= Inside.CharLiteral; } break; } if (!IsInComment && !IsInStringOrChar && !readPreprocessorExpression) { if ((wordBuf.Length == 0 ? char.IsLetter(ch) : char.IsLetterOrDigit(ch)) || ch == '_') { wordBuf.Append(ch); } else { if (inside.HasFlag(Inside.PreProcessor)) { if (wordBuf.ToString() == "endif") { inside &= ~Inside.PreProcessorComment; } else if (wordBuf.ToString() == "if") { readPreprocessorExpression = true; } else if (wordBuf.ToString() == "elif") { inside &= ~Inside.PreProcessorComment; readPreprocessorExpression = true; } } else { CheckKeyword(wordBuf.ToString()); } wordBuf.Length = 0; } } if (addContinuation) { indent.Push(IndentType.Continuation); addContinuation = false; } IsLineStart &= ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; pc = ch; if (ch != '\n' && ch != '\r') { col++; } }