diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/LexAVE.cxx | 316 |
1 files changed, 176 insertions, 140 deletions
diff --git a/src/LexAVE.cxx b/src/LexAVE.cxx index dfd15f02f..900aea317 100644 --- a/src/LexAVE.cxx +++ b/src/LexAVE.cxx @@ -1,188 +1,224 @@ // SciTE - Scintilla based Text Editor /** @file LexAVE.cxx ** Lexer for Avenue. + ** + ** Written by Alexey Yutkin <yutkin@geol.msu.ru>. **/ -// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> +// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <ctype.h> -#include <stdio.h> #include <stdarg.h> +#include <stdio.h> +#include <fcntl.h> #include "Platform.h" #include "PropSet.h" #include "Accessor.h" +#include "StyleContext.h" #include "KeyWords.h" #include "Scintilla.h" #include "SciLexer.h" -static void ColouriseAveDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + + +static inline bool IsAWordChar(const int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); +} +static inline bool IsEnumChar(const int ch) { + return (ch < 0x80) && (isalnum(ch)|| ch == '_'); +} +static inline bool IsANumberChar(const int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '.' ); +} + +inline bool IsAWordStart(const int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '_'); +} + +inline bool isAveOperator(char ch) { + if (isalnum(ch)) + return false; + // '.' left out as it is used to make up numbers + if (ch == '*' || ch == '/' || ch == '-' || ch == '+' || + ch == '(' || ch == ')' || ch == '=' || + ch == '{' || ch == '}' || + ch == '[' || ch == ']' || ch == ';' || + ch == '<' || ch == '>' || ch == ',' || + ch == '.' ) + return true; + return false; +} + +static void ColouriseAveDoc( + unsigned int startPos, + int length, + int initStyle, + WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; + WordList &keywords2 = *keywordlists[1]; + WordList &keywords3 = *keywordlists[2]; + WordList &keywords4 = *keywordlists[3]; + WordList &keywords5 = *keywordlists[4]; + WordList &keywords6 = *keywordlists[5]; + + // Do not leak onto next line + if (initStyle == SCE_AVE_STRINGEOL) { + initStyle = SCE_AVE_DEFAULT; + } - styler.StartAt(startPos); + StyleContext sc(startPos, length, initStyle, styler); - bool fold = styler.GetPropertyInt("fold") != 0; - int lineCurrent = styler.GetLine(startPos); - int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; - int levelCurrent = levelPrev; + for (; sc.More(); sc.Forward()) { + if (sc.atLineEnd) { + // Update the line state, so it can be seen by next line + int currentLine = styler.GetLine(sc.currentPos); + styler.SetLineState(currentLine, 0); + } + if (sc.atLineStart && (sc.state == SCE_AVE_STRING)) { + // Prevent SCE_AVE_STRINGEOL from leaking back to previous line + sc.SetState(SCE_AVE_STRING); + } - int state = initStyle; - if (state == SCE_AVE_STRINGEOL) // Does not leak onto next line - state = SCE_AVE_DEFAULT; - char chNext = styler[startPos]; - unsigned int lengthDoc = startPos + length; - int visibleChars = 0; - styler.StartSegment(startPos); - for (unsigned int i = startPos; i < lengthDoc; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { - // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) - // Avoid triggering two times on Dos/Win - // End of line - if (state == SCE_AVE_STRINGEOL) { - styler.ColourTo(i, state); - state = SCE_AVE_DEFAULT; + // Determine if the current state should terminate. + if (sc.state == SCE_AVE_OPERATOR) { + sc.SetState(SCE_AVE_DEFAULT); + } else if (sc.state == SCE_AVE_NUMBER) { + if (!IsANumberChar(sc.ch)) { + sc.SetState(SCE_AVE_DEFAULT); } - if (fold) { - int lev = levelPrev; - if (visibleChars == 0) - lev |= SC_FOLDLEVELWHITEFLAG; - if ((levelCurrent > levelPrev) && (visibleChars > 0)) - lev |= SC_FOLDLEVELHEADERFLAG; - styler.SetLevel(lineCurrent, lev); - lineCurrent++; - levelPrev = levelCurrent; + } else if (sc.state == SCE_AVE_ENUM) { + if (!IsEnumChar(sc.ch)) { + sc.SetState(SCE_AVE_DEFAULT); } - visibleChars = 0; - } - if (!isspace(ch)) - visibleChars++; - if (styler.IsLeadByte(ch)) { - chNext = styler.SafeGetCharAt(i + 2); - i += 1; - continue; - } - - if (state == SCE_AVE_DEFAULT) { - if (iswordstart(ch) || (ch == '.') ) { - styler.ColourTo(i-1, state); - state = SCE_AVE_IDENTIFIER; - } else if (ch == '\'') { - styler.ColourTo(i-1, state); - state = SCE_AVE_COMMENT; - } else if (ch == '\"') { - styler.ColourTo(i-1, state); - state = SCE_AVE_STRING; - } else if (ch == '#') { - styler.ColourTo(i-1, state); - state = SCE_AVE_ENUM; - } else if (isoperator(ch) ) { - styler.ColourTo(i-1, state); - styler.ColourTo(i, SCE_AVE_OPERATOR); + } else if (sc.state == SCE_AVE_IDENTIFIER) { + if (!IsAWordChar(sc.ch) || (sc.ch == '.')) { + char s[100]; + //sc.GetCurrent(s, sizeof(s)); + sc.GetCurrentLowered(s, sizeof(s)); + if (keywords.InList(s)) { + sc.ChangeState(SCE_AVE_WORD); + } else if (keywords2.InList(s)) { + sc.ChangeState(SCE_AVE_WORD2); + } else if (keywords3.InList(s)) { + sc.ChangeState(SCE_AVE_WORD3); + } else if (keywords4.InList(s)) { + sc.ChangeState(SCE_AVE_WORD4); + } else if (keywords5.InList(s)) { + sc.ChangeState(SCE_AVE_WORD5); + } else if (keywords6.InList(s)) { + sc.ChangeState(SCE_AVE_WORD6); + } + sc.SetState(SCE_AVE_DEFAULT); } - } - else if (state == SCE_AVE_COMMENT) { - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); - state = SCE_AVE_DEFAULT; + } else if (sc.state == SCE_AVE_COMMENT) { + if (sc.atLineEnd) { + sc.SetState(SCE_AVE_DEFAULT); } - } - else if (state == SCE_AVE_ENUM) { - if (isoperator(ch) || ch == ' ' || ch == '\'' || ch == '\r' || ch == '\n') { - styler.ColourTo(i-1, state); - state = SCE_AVE_DEFAULT; + } else if (sc.state == SCE_AVE_STRING) { + if (sc.ch == '\"') { + sc.ForwardSetState(SCE_AVE_DEFAULT); + } else if (sc.atLineEnd) { + sc.ChangeState(SCE_AVE_STRINGEOL); + sc.ForwardSetState(SCE_AVE_DEFAULT); } } - else if (state == SCE_AVE_STRING) { - if (ch == '\"') { - if (chNext == '\"') { - i++; - ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - } else - { - styler.ColourTo(i, state); - state = SCE_AVE_DEFAULT; - } - } else if (chNext == '\r' || chNext == '\n') { - styler.ColourTo(i-1, SCE_AVE_STRINGEOL); - state = SCE_AVE_STRINGEOL; + + // Determine if a new state should be entered. + if (sc.state == SCE_AVE_DEFAULT) { + if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { + sc.SetState(SCE_AVE_NUMBER); + } else if (IsAWordStart(sc.ch)) { + sc.SetState(SCE_AVE_IDENTIFIER); + } else if (sc.Match('\"')) { + sc.SetState(SCE_AVE_STRING); + } else if (sc.Match('\'')) { + sc.SetState(SCE_AVE_COMMENT); + sc.Forward(); + } else if (isAveOperator(static_cast<char>(sc.ch))) { + sc.SetState(SCE_AVE_OPERATOR); + } else if (sc.Match('#')) { + sc.SetState(SCE_AVE_ENUM); + sc.Forward(); } } - if ((state == SCE_AVE_IDENTIFIER)) { - if (!iswordchar(ch) || ch == '.' ) { - char s[100]; - unsigned int start = styler.GetStartSegment(); - unsigned int end = i - 1; - for (unsigned int ii = 0; ii < end - start + 1 && ii < 30; ii++) { - s[ii] = static_cast<char>(tolower(styler[start + ii])); - s[ii + 1] = '\0'; - } - - char chAttr = SCE_AVE_IDENTIFIER; - - if (isdigit(s[0])) - chAttr = SCE_AVE_NUMBER; - else { - if ((strcmp(s, "for") == 0) || (strcmp(s, "if") == 0) || (strcmp(s, "while") == 0)) - { - levelCurrent +=1; - chAttr = SCE_AVE_STATEMENT; - } - - if (strcmp(s, "end") == 0) - { - levelCurrent -=1; - chAttr = SCE_AVE_STATEMENT; - } + } + sc.Complete(); +} - if ( (strcmp(s, "then") == 0) || (strcmp(s, "else") == 0) || (strcmp(s, "break") == 0) || - (strcmp(s, "each") == 0) || - (strcmp(s, "exit") == 0) || (strcmp(s, "continue") == 0) || (strcmp(s, "return") == 0) || - (strcmp(s, "by") == 0) || (strcmp(s, "in") == 0) || (strcmp(s, "elseif") == 0)) - { - chAttr = SCE_AVE_STATEMENT; - } +static void FoldAveDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[], + Accessor &styler) { + unsigned int lengthDoc = startPos + length; + int visibleChars = 0; + int lineCurrent = styler.GetLine(startPos); + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; + int levelCurrent = levelPrev; + char chNext = static_cast<char>(tolower(styler[startPos])); + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + int styleNext = styler.StyleAt(startPos); + char s[10]; - if ((strcmp(s, "av") == 0) || (strcmp(s, "self") == 0)) - { - chAttr = SCE_AVE_KEYWORD; + for (unsigned int i = startPos; i < lengthDoc; i++) { + char ch = static_cast<char>(tolower(chNext)); + chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1))); + int style = styleNext; + styleNext = styler.StyleAt(i + 1); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + if (style == SCE_AVE_WORD) { + if (ch == 't' || ch == 'f' || ch == 'w' || ch == 'e') { + for (unsigned int j = 0; j < 6; j++) { + if (!iswordchar(styler[i + j])) { + break; } + s[j] = static_cast<char>(tolower(styler[i + j])); + s[j + 1] = '\0'; + } - if (keywords.InList(s)) - { - chAttr = SCE_AVE_WORD; - } + if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) { + levelCurrent++; } - styler.ColourTo(end, chAttr); - state = SCE_AVE_DEFAULT; - - if (ch == '\'') { - state = SCE_AVE_COMMENT; - } else if (ch == '\"') { - state = SCE_AVE_STRING; - } else if (isoperator(ch)) { - styler.ColourTo(i, SCE_AVE_OPERATOR); + if ((strcmp(s, "end") == 0)) { + levelCurrent--; } } + } else if (style == SCE_AVE_OPERATOR) { + if (ch == '{' || ch == '(') { + levelCurrent++; + } else if (ch == '}' || ch == ')') { + levelCurrent--; + } } + if (atEOL) { + int lev = levelPrev; + if (visibleChars == 0 && foldCompact) { + lev |= SC_FOLDLEVELWHITEFLAG; + } + if ((levelCurrent > levelPrev) && (visibleChars > 0)) { + lev |= SC_FOLDLEVELHEADERFLAG; + } + if (lev != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, lev); + } + lineCurrent++; + levelPrev = levelCurrent; + visibleChars = 0; + } + if (!isspacechar(ch)) { + visibleChars++; + } } - styler.ColourTo(lengthDoc - 1, state); - // Fill in the real level of the next line, keeping the current flags as they will be filled in later - if (fold) { - int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; - styler.SetLevel(lineCurrent, levelPrev | flagsNext); - } + int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; + styler.SetLevel(lineCurrent, levelPrev | flagsNext); } -LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave"); +LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave", FoldAveDoc); + |