diff options
Diffstat (limited to 'lexers/LexBasic.cxx')
-rw-r--r-- | lexers/LexBasic.cxx | 88 |
1 files changed, 72 insertions, 16 deletions
diff --git a/lexers/LexBasic.cxx b/lexers/LexBasic.cxx index bc8fcee47..55285201f 100644 --- a/lexers/LexBasic.cxx +++ b/lexers/LexBasic.cxx @@ -49,17 +49,18 @@ using namespace Scintilla; * 8 - decimal digit * 16 - hex digit * 32 - bin digit + * 64 - letter */ static int character_classification[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2, - 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2, - 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4, - 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2, + 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2, + 2, 84, 84, 84, 84, 84, 84, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 2, 2, 2, 68, + 2, 84, 84, 84, 84, 84, 84, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 2, 2, 2, 0 }; static bool IsSpace(int c) { @@ -86,6 +87,10 @@ static bool IsBinDigit(int c) { return c < 128 && (character_classification[c] & 32); } +static bool IsLetter(int c) { + return c < 128 && (character_classification[c] & 64); +} + static int LowerCase(int c) { if (c >= 'A' && c <= 'Z') @@ -126,13 +131,23 @@ static int CheckPureFoldPoint(char const *token, int &level) { static int CheckFreeFoldPoint(char const *token, int &level) { if (!strcmp(token, "function") || !strcmp(token, "sub") || - !strcmp(token, "type")) { + !strcmp(token, "enum") || + !strcmp(token, "type") || + !strcmp(token, "union") || + !strcmp(token, "property") || + !strcmp(token, "destructor") || + !strcmp(token, "constructor")) { level |= SC_FOLDLEVELHEADERFLAG; return 1; } if (!strcmp(token, "end function") || !strcmp(token, "end sub") || - !strcmp(token, "end type")) { + !strcmp(token, "end enum") || + !strcmp(token, "end type") || + !strcmp(token, "end union") || + !strcmp(token, "end property") || + !strcmp(token, "end destructor") || + !strcmp(token, "end constructor")) { return -1; } return 0; @@ -219,9 +234,9 @@ class LexerBasic : public ILexer { OptionSetBasic osBasic; public: LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) : - comment_char(comment_char_), - CheckFoldPoint(CheckFoldPoint_), - osBasic(wordListDescriptions) { + comment_char(comment_char_), + CheckFoldPoint(CheckFoldPoint_), + osBasic(wordListDescriptions) { } virtual ~LexerBasic() { } @@ -302,6 +317,7 @@ void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle bool wasfirst = true, isfirst = true; // true if first token in a line styler.StartAt(startPos); + int styleBeforeKeyword = SCE_B_DEFAULT; StyleContext sc(startPos, length, initStyle, styler); @@ -367,14 +383,44 @@ void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle if (sc.atLineEnd) { sc.SetState(SCE_B_DEFAULT); } + } else if (sc.state == SCE_B_DOCLINE) { + if (sc.atLineEnd) { + sc.SetState(SCE_B_DEFAULT); + } else if (sc.ch == '\\' || sc.ch == '@') { + if (IsLetter(sc.chNext) && sc.chPrev != '\\') { + styleBeforeKeyword = sc.state; + sc.SetState(SCE_B_DOCKEYWORD); + }; + } + } else if (sc.state == SCE_B_DOCKEYWORD) { + if (IsSpace(sc.ch)) { + sc.SetState(styleBeforeKeyword); + } else if (sc.atLineEnd && styleBeforeKeyword == SCE_B_DOCLINE) { + sc.SetState(SCE_B_DEFAULT); + } + } else if (sc.state == SCE_B_COMMENTBLOCK) { + if (sc.Match("\'/")) { + sc.Forward(); + sc.ForwardSetState(SCE_B_DEFAULT); + } + } else if (sc.state == SCE_B_DOCBLOCK) { + if (sc.Match("\'/")) { + sc.Forward(); + sc.ForwardSetState(SCE_B_DEFAULT); + } else if (sc.ch == '\\' || sc.ch == '@') { + if (IsLetter(sc.chNext) && sc.chPrev != '\\') { + styleBeforeKeyword = sc.state; + sc.SetState(SCE_B_DOCKEYWORD); + }; + } } if (sc.atLineStart) isfirst = true; if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) { - if (isfirst && sc.Match('.')) { - sc.SetState(SCE_B_LABEL); + if (isfirst && sc.Match('.') && comment_char != '\'') { + sc.SetState(SCE_B_LABEL); } else if (isfirst && sc.Match('#')) { wasfirst = isfirst; sc.SetState(SCE_B_IDENTIFIER); @@ -383,8 +429,18 @@ void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle // up in freebasic with SCE_B_PREPROCESSOR. if (comment_char == '\'' && sc.Match(comment_char, '$')) sc.SetState(SCE_B_PREPROCESSOR); - else + else if (sc.Match("\'*") || sc.Match("\'!")) { + sc.SetState(SCE_B_DOCLINE); + } else { sc.SetState(SCE_B_COMMENT); + } + } else if (sc.Match("/\'")) { + if (sc.Match("/\'*") || sc.Match("/\'!")) { // Support of gtk-doc/Doxygen doc. style + sc.SetState(SCE_B_DOCBLOCK); + } else { + sc.SetState(SCE_B_COMMENTBLOCK); + } + sc.Forward(); // Eat the ' so it isn't used for the end of the comment } else if (sc.Match('"')) { sc.SetState(SCE_B_STRING); } else if (IsDigit(sc.ch)) { |