diff options
Diffstat (limited to 'lexers/LexVerilog.cxx')
-rw-r--r-- | lexers/LexVerilog.cxx | 205 |
1 files changed, 137 insertions, 68 deletions
diff --git a/lexers/LexVerilog.cxx b/lexers/LexVerilog.cxx index ed39c2b17..8062c09cf 100644 --- a/lexers/LexVerilog.cxx +++ b/lexers/LexVerilog.cxx @@ -36,13 +36,28 @@ static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '$'); } +static inline bool AllUpperCase(const char *a) { + while (*a) { + if (*a >= 'a' && *a <= 'z') return false; + a++; + } + return true; +} + static void ColouriseVerilogDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { + const int kwOther=0, kwDot=0x100, kwInput=0x200, kwOutput=0x300, kwInout=0x400; + int lineState = kwOther; + WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; + WordList &keywords5 = *keywordlists[4]; + + int curLine = styler.GetLine(startPos); + if (curLine > 0) lineState = styler.GetLineState(curLine - 1); // Do not leak onto next line if (initStyle == SCE_V_STRINGEOL) @@ -51,6 +66,12 @@ static void ColouriseVerilogDoc(unsigned int startPos, int length, int initStyle StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { + curLine = styler.GetLine(sc.currentPos); + + if (sc.atLineEnd) { + // Update the line state, so it can be seen by next line + styler.SetLineState(curLine, lineState); + } if (sc.atLineStart && (sc.state == SCE_V_STRING)) { // Prevent SCE_V_STRINGEOL from leaking back to previous line @@ -68,42 +89,87 @@ static void ColouriseVerilogDoc(unsigned int startPos, int length, int initStyle } } + // for comment keyword + if (sc.state == SCE_V_COMMENT_WORD && !IsAWordChar(sc.ch)) { + char s[100]; + int state = lineState & 0xff; + sc.GetCurrent(s, sizeof(s)); + if (keywords5.InList(s)) { + sc.ChangeState(SCE_V_COMMENT_WORD); + } else { + sc.ChangeState(state); + } + sc.SetState(state); + } // Determine if the current state should terminate. if (sc.state == SCE_V_OPERATOR) { sc.SetState(SCE_V_DEFAULT); } else if (sc.state == SCE_V_NUMBER) { - if (!IsAWordChar(sc.ch)) { + if (!(IsAWordChar(sc.ch) || (sc.ch == '?'))) { sc.SetState(SCE_V_DEFAULT); } } else if (sc.state == SCE_V_IDENTIFIER) { if (!IsAWordChar(sc.ch) || (sc.ch == '.')) { char s[100]; - sc.GetCurrent(s, sizeof(s)); - if (keywords.InList(s)) { + lineState &= 0xff00; + + sc.GetCurrent(s, sizeof(s)); + + if (strcmp(s, "input") == 0) { + lineState = kwInput; + sc.ChangeState(SCE_V_INPUT); + } else if (strcmp(s, "output") == 0) { + lineState = kwOutput; + sc.ChangeState(SCE_V_OUTPUT); + } else if (strcmp(s, "inout") == 0) { + lineState = kwInout; + sc.ChangeState(SCE_V_INOUT); + + } else if (lineState == kwInput) { + sc.ChangeState(SCE_V_INPUT); + } else if (lineState == kwOutput) { + sc.ChangeState(SCE_V_OUTPUT); + } else if (lineState == kwInout) { + sc.ChangeState(SCE_V_INOUT); + } else if (lineState == kwDot) { + lineState = kwOther; + sc.ChangeState(SCE_V_PORT_CONNECT); + + } else if (keywords.InList(s)) { sc.ChangeState(SCE_V_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_V_WORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_V_WORD3); - } else if (keywords4.InList(s)) { + } else if (keywords4.InList(s)) { + sc.ChangeState(SCE_V_USER); + + } else if (AllUpperCase(s)) { sc.ChangeState(SCE_V_USER); } + sc.SetState(SCE_V_DEFAULT); } } else if (sc.state == SCE_V_PREPROCESSOR) { - if (!IsAWordChar(sc.ch)) { - sc.SetState(SCE_V_DEFAULT); - } + if (!IsAWordChar(sc.ch)) { + sc.SetState(SCE_V_DEFAULT); + } } else if (sc.state == SCE_V_COMMENT) { if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_V_DEFAULT); + } else if (IsAWordStart(sc.ch)) { + lineState = sc.state | (lineState & 0xff00); + sc.SetState(SCE_V_COMMENT_WORD); } } else if (sc.state == SCE_V_COMMENTLINE || sc.state == SCE_V_COMMENTLINEBANG) { if (sc.atLineStart) { sc.SetState(SCE_V_DEFAULT); + } else if (IsAWordStart(sc.ch)) { + lineState = sc.state | (lineState & 0xff00); + sc.SetState(SCE_V_COMMENT_WORD); } - } else if (sc.state == SCE_V_STRING) { + } else if (sc.state == SCE_V_STRING) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); @@ -123,7 +189,7 @@ static void ColouriseVerilogDoc(unsigned int startPos, int length, int initStyle } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_V_IDENTIFIER); } else if (sc.Match('/', '*')) { - sc.SetState(SCE_V_COMMENT); + sc.SetState(SCE_V_COMMENT); 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 @@ -140,9 +206,12 @@ static void ColouriseVerilogDoc(unsigned int startPos, int length, int initStyle } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); if (sc.atLineEnd) { sc.SetState(SCE_V_DEFAULT); + styler.SetLineState(curLine, lineState); } } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '#') { sc.SetState(SCE_V_OPERATOR); + if (sc.ch == '.') lineState = kwDot; + if (sc.ch == ';') lineState = kwOther; } } } @@ -178,12 +247,12 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; - // Verilog specific folding options: - // fold_at_module - - // Generally used methodology in verilog code is - // one module per file, so folding at module definition is useless. - // fold_at_brace/parenthese - - // Folding of long port lists can be convenient. + // Verilog specific folding options: + // fold_at_module - + // Generally used methodology in verilog code is + // one module per file, so folding at module definition is useless. + // fold_at_brace/parenthese - + // Folding of long port lists can be convenient. bool foldAtModule = styler.GetPropertyInt("fold.verilog.flags", 0) != 0; bool foldAtBrace = 1; bool foldAtParenthese = 1; @@ -246,63 +315,63 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle } } } - if (style == SCE_V_OPERATOR) { - if (foldAtParenthese) { - if (ch == '(') { - levelNext++; - } else if (ch == ')') { - levelNext--; + if (style == SCE_V_OPERATOR) { + if (foldAtParenthese) { + if (ch == '(') { + levelNext++; + } else if (ch == ')') { + levelNext--; + } + } + } + if (style == SCE_V_OPERATOR) { + if (foldAtBrace) { + if (ch == '{') { + levelNext++; + } else if (ch == '}') { + levelNext--; + } } - } } - if (style == SCE_V_OPERATOR) { - if (foldAtBrace) { - if (ch == '{') { + if (style == SCE_V_WORD && stylePrev != SCE_V_WORD) { + unsigned int j = i; + if (styler.Match(j, "case") || + styler.Match(j, "casex") || + styler.Match(j, "casez") || + styler.Match(j, "class") || + styler.Match(j, "function") || + styler.Match(j, "generate") || + styler.Match(j, "covergroup") || + styler.Match(j, "package") || + styler.Match(j, "primitive") || + styler.Match(j, "program") || + styler.Match(j, "sequence") || + styler.Match(j, "specify") || + styler.Match(j, "table") || + styler.Match(j, "task") || + styler.Match(j, "fork") || + (styler.Match(j, "module") && foldAtModule) || + styler.Match(j, "begin")) { levelNext++; - } else if (ch == '}') { + } else if (styler.Match(j, "endcase") || + styler.Match(j, "endclass") || + styler.Match(j, "endfunction") || + styler.Match(j, "endgenerate") || + styler.Match(j, "endgroup") || + styler.Match(j, "endpackage") || + styler.Match(j, "endprimitive") || + styler.Match(j, "endprogram") || + styler.Match(j, "endsequence") || + styler.Match(j, "endspecify") || + styler.Match(j, "endtable") || + styler.Match(j, "endtask") || + styler.Match(j, "join") || + styler.Match(j, "join_any") || + styler.Match(j, "join_none") || + (styler.Match(j, "endmodule") && foldAtModule) || + (styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j + 3)))) { levelNext--; } - } - } - if (style == SCE_V_WORD && stylePrev != SCE_V_WORD) { - unsigned int j = i; - if (styler.Match(j, "case") || - styler.Match(j, "casex") || - styler.Match(j, "casez") || - styler.Match(j, "class") || - styler.Match(j, "function") || - styler.Match(j, "generate") || - styler.Match(j, "covergroup") || - styler.Match(j, "package") || - styler.Match(j, "primitive") || - styler.Match(j, "program") || - styler.Match(j, "sequence") || - styler.Match(j, "specify") || - styler.Match(j, "table") || - styler.Match(j, "task") || - styler.Match(j, "fork") || - (styler.Match(j, "module") && foldAtModule) || - styler.Match(j, "begin")) { - levelNext++; - } else if (styler.Match(j, "endcase") || - styler.Match(j, "endclass") || - styler.Match(j, "endfunction") || - styler.Match(j, "endgenerate") || - styler.Match(j, "endgroup") || - styler.Match(j, "endpackage") || - styler.Match(j, "endprimitive") || - styler.Match(j, "endprogram") || - styler.Match(j, "endsequence") || - styler.Match(j, "endspecify") || - styler.Match(j, "endtable") || - styler.Match(j, "endtask") || - styler.Match(j, "join") || - styler.Match(j, "join_any") || - styler.Match(j, "join_none") || - (styler.Match(j, "endmodule") && foldAtModule) || - (styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) { - levelNext--; - } } if (atEOL) { int levelUse = levelCurrent; @@ -337,7 +406,7 @@ static const char * const verilogWordLists[] = { "Secondary keywords and identifiers", "System Tasks", "User defined tasks and identifiers", - "Unused", + "Documentation comment keywords", 0, }; |