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 | 
