diff options
-rw-r--r-- | lexers/LexVerilog.cxx | 125 |
1 files changed, 72 insertions, 53 deletions
diff --git a/lexers/LexVerilog.cxx b/lexers/LexVerilog.cxx index 82b75844f..f21b19de2 100644 --- a/lexers/LexVerilog.cxx +++ b/lexers/LexVerilog.cxx @@ -207,7 +207,7 @@ class LexerVerilog : public ILexerWithSubStyles { // foldExternFlag: EOL while parsing an extern function/task declaration terminated by ';' // foldWaitDisableFlag: EOL while parsing wait or disable statement, terminated by "fork" or '(' // typdefFlag: EOL while parsing typedef statement, terminated by ';' - enum {foldExternFlag = 0x01, foldWaitDisableFlag = 0x02, typedefFlag = 0x04}; + enum {foldExternFlag = 0x01, foldWaitDisableFlag = 0x02, typedefFlag = 0x04, protectedFlag = 0x08}; // map using line number as key to store fold state information std::map<int, int> foldState; @@ -395,7 +395,7 @@ void SCI_METHOD LexerVerilog::Lex(unsigned int startPos, int length, int initSty { LexAccessor styler(pAccess); - const int kwOther=0, kwDot=0x100, kwInput=0x200, kwOutput=0x300, kwInout=0x400; + const int kwOther=0, kwDot=0x100, kwInput=0x200, kwOutput=0x300, kwInout=0x400, kwProtected=0x800; int lineState = kwOther; bool continuationLine = false; @@ -445,6 +445,7 @@ void SCI_METHOD LexerVerilog::Lex(unsigned int startPos, int length, int initSty int activitySet = preproc.IsInactive() ? activeFlag : 0; int lineEndNext = styler.LineEnd(curLine); bool isEscapedId = false; // true when parsing an escaped Identifier + bool isProtected = lineState&kwProtected; // true when parsing a protected region for (; sc.More(); sc.Forward()) { if (sc.atLineStart) { @@ -601,21 +602,7 @@ void SCI_METHOD LexerVerilog::Lex(unsigned int startPos, int length, int initSty // Determine if a new state should be entered. if (MaskActive(sc.state) == SCE_V_DEFAULT) { - if (IsADigit(sc.ch) || (sc.ch == '\'') || (sc.ch == '.' && IsADigit(sc.chNext))) { - sc.SetState(SCE_V_NUMBER|activitySet); - } else if (IsAWordStart(sc.ch)) { - sc.SetState(SCE_V_IDENTIFIER|activitySet); - } else if (sc.Match('/', '*')) { - sc.SetState(SCE_V_COMMENT|activitySet); - sc.Forward(); // Eat the * so it isn't used for the end of the comment - } else if (sc.Match('/', '/')) { - if (sc.Match("//!")) // Nice to have a different comment style - sc.SetState(SCE_V_COMMENTLINEBANG|activitySet); - else - sc.SetState(SCE_V_COMMENTLINE|activitySet); - } else if (sc.ch == '\"') { - sc.SetState(SCE_V_STRING|activitySet); - } else if (sc.ch == '`') { + if (sc.ch == '`') { sc.SetState(SCE_V_PREPROCESSOR|activitySet); // Skip whitespace between ` and preprocessor word do { @@ -625,7 +612,15 @@ void SCI_METHOD LexerVerilog::Lex(unsigned int startPos, int length, int initSty sc.SetState(SCE_V_DEFAULT|activitySet); styler.SetLineState(curLine, lineState); } else { - if (options.trackPreprocessor) { + if (sc.Match("protected")) { + isProtected = true; + lineState |= kwProtected; + styler.SetLineState(curLine, lineState); + } else if (sc.Match("endprotected")) { + isProtected = false; + lineState &= ~kwProtected; + styler.SetLineState(curLine, lineState); + } else if (!isProtected && options.trackPreprocessor) { if (sc.Match("ifdef") || sc.Match("ifndef")) { bool isIfDef = sc.Match("ifdef"); int i = isIfDef ? 5 : 6; @@ -729,14 +724,30 @@ void SCI_METHOD LexerVerilog::Lex(unsigned int startPos, int length, int initSty } } } - } else if (sc.ch == '\\') { - // escaped identifier, everything is ok up to whitespace - isEscapedId = true; - sc.SetState(SCE_V_IDENTIFIER|activitySet); - } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '#') { - sc.SetState(SCE_V_OPERATOR|activitySet); - if (sc.ch == '.') lineState = kwDot; - if (sc.ch == ';') lineState = kwOther; + } else if (!isProtected) { + if (IsADigit(sc.ch) || (sc.ch == '\'') || (sc.ch == '.' && IsADigit(sc.chNext))) { + sc.SetState(SCE_V_NUMBER|activitySet); + } else if (IsAWordStart(sc.ch)) { + sc.SetState(SCE_V_IDENTIFIER|activitySet); + } else if (sc.Match('/', '*')) { + sc.SetState(SCE_V_COMMENT|activitySet); + sc.Forward(); // Eat the * so it isn't used for the end of the comment + } else if (sc.Match('/', '/')) { + if (sc.Match("//!")) // Nice to have a different comment style + sc.SetState(SCE_V_COMMENTLINEBANG|activitySet); + else + sc.SetState(SCE_V_COMMENTLINE|activitySet); + } else if (sc.ch == '\"') { + sc.SetState(SCE_V_STRING|activitySet); + } else if (sc.ch == '\\') { + // escaped identifier, everything is ok up to whitespace + isEscapedId = true; + sc.SetState(SCE_V_IDENTIFIER|activitySet); + } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '#') { + sc.SetState(SCE_V_OPERATOR|activitySet); + if (sc.ch == '.') lineState = kwDot; + if (sc.ch == ';') lineState = kwOther; + } } } if (isEscapedId && isspacechar(sc.ch)) { @@ -822,39 +833,47 @@ void SCI_METHOD LexerVerilog::Fold(unsigned int startPos, int length, int initSt style = styleNext; styleNext = MaskActive(styler.StyleAt(i + 1)); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); - if (options.foldComment && IsStreamCommentStyle(style)) { - if (!IsStreamCommentStyle(stylePrev)) { - levelNext++; - } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { - // Comments don't end at end of line and the next character may be unstyled. - levelNext--; + if (!(stateCurrent & protectedFlag)) { + if (options.foldComment && IsStreamCommentStyle(style)) { + if (!IsStreamCommentStyle(stylePrev)) { + levelNext++; + } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { + // Comments don't end at end of line and the next character may be unstyled. + levelNext--; + } } - } - if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) - { - if (!IsCommentLine(lineCurrent - 1, styler) - && IsCommentLine(lineCurrent + 1, styler)) - levelNext++; - else if (IsCommentLine(lineCurrent - 1, styler) - && !IsCommentLine(lineCurrent+1, styler)) - levelNext--; - } - if (options.foldComment && (style == SCE_V_COMMENTLINE)) { - if ((ch == '/') && (chNext == '/')) { - char chNext2 = styler.SafeGetCharAt(i + 2); - if (chNext2 == '{') { + if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) + { + if (!IsCommentLine(lineCurrent - 1, styler) + && IsCommentLine(lineCurrent + 1, styler)) levelNext++; - } else if (chNext2 == '}') { + else if (IsCommentLine(lineCurrent - 1, styler) + && !IsCommentLine(lineCurrent+1, styler)) levelNext--; + } + if (options.foldComment && (style == SCE_V_COMMENTLINE)) { + if ((ch == '/') && (chNext == '/')) { + char chNext2 = styler.SafeGetCharAt(i + 2); + if (chNext2 == '{') { + levelNext++; + } else if (chNext2 == '}') { + levelNext--; + } } } } - if (options.foldPreprocessor && (style == SCE_V_PREPROCESSOR)) { - if (ch == '`') { - unsigned int j = i + 1; - while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { - j++; - } + if (ch == '`') { + unsigned int j = i + 1; + while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { + j++; + } + if (styler.Match(j, "protected")) { + stateCurrent |= protectedFlag; + levelNext++; + } else if (styler.Match(j, "endprotected")) { + stateCurrent &= ~protectedFlag; + levelNext--; + } else if (!(stateCurrent & protectedFlag) && options.foldPreprocessor && (style == SCE_V_PREPROCESSOR)) { if (styler.Match(j, "if")) { if (options.foldPreprocessorElse) { // Measure the minimum before a begin to allow |