diff options
author | nyamatongwe <unknown> | 2000-11-08 08:27:08 +0000 |
---|---|---|
committer | nyamatongwe <unknown> | 2000-11-08 08:27:08 +0000 |
commit | 3cb439e2f18542ea244d4d21aeeb01a606caea56 (patch) | |
tree | f5085881cbdb3f8215204eda19184bb3ee3ef1b6 /src/LexPascal.cxx | |
parent | 096c56c2271e8055298f3dfc244c2ae50321edcc (diff) | |
download | scintilla-mirror-3cb439e2f18542ea244d4d21aeeb01a606caea56.tar.gz |
Initial version by Laurent le Tynevez.
Diffstat (limited to 'src/LexPascal.cxx')
-rw-r--r-- | src/LexPascal.cxx | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/LexPascal.cxx b/src/LexPascal.cxx new file mode 100644 index 000000000..b9aed807b --- /dev/null +++ b/src/LexPascal.cxx @@ -0,0 +1,208 @@ +// SciTE - Scintilla based Text Editor +// LexPascal.cxx - lexer for Pascal + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <stdio.h> +#include <stdarg.h> + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + + +static int classifyWordPascal(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { + char s[100]; + for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { + s[i] = static_cast<char>(tolower(styler[start + i])); + s[i + 1] = '\0'; + } + int lev= 0; + char chAttr = SCE_C_IDENTIFIER; + if (isdigit(s[0]) || (s[0] == '.')){ + chAttr = SCE_C_NUMBER; + } + else { + if (keywords.InList(s)) { + chAttr = SCE_C_WORD; + if (strcmp(s, "begin") == 0 || strcmp(s, "object") == 0) + lev=1; + else if (strcmp(s, "end") == 0) + lev=-1; + } + } + styler.ColourTo(end, chAttr); + return lev; +} + +static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + + WordList &keywords = *keywordlists[0]; + + styler.StartAt(startPos); + + bool fold = styler.GetPropertyInt("fold"); + bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor"); + int lineCurrent = styler.GetLine(startPos); + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; + int levelCurrent = levelPrev; + + int state = initStyle; + if (state == SCE_C_STRINGEOL) // Does not leak onto next line + state = SCE_C_DEFAULT; + char chPrev = ' '; + 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_C_STRINGEOL) { + styler.ColourTo(i, state); + state = SCE_C_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; + } + visibleChars = 0; + } + if (!isspace(ch)) + visibleChars++; + + if (styler.IsLeadByte(ch)) { + chNext = styler.SafeGetCharAt(i + 2); + chPrev = ' '; + i += 1; + continue; + } + + if (state == SCE_C_DEFAULT) { + if (iswordstart(ch) || (ch == '@')) { + styler.ColourTo(i-1, state); + state = SCE_C_IDENTIFIER; + } else if (ch == '{' && chNext != '$' && chNext != '&') { + styler.ColourTo(i-1, state); + state = SCE_C_COMMENT; + } else if (ch == '/' && chNext == '/') { + styler.ColourTo(i-1, state); + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + styler.ColourTo(i-1, state); + state = SCE_C_STRING; + } else if (ch == '\'') { + styler.ColourTo(i-1, state); + state = SCE_C_CHARACTER; + } else if (ch == '{' && (chNext == '$' || chNext=='&') && visibleChars == 1) { + styler.ColourTo(i-1, state); + state = SCE_C_PREPROCESSOR; + } else if (isoperator(ch)) { + styler.ColourTo(i-1, state); + styler.ColourTo(i, SCE_C_OPERATOR); + + } + } else if (state == SCE_C_IDENTIFIER) { + if (!iswordchar(ch)) { + int levelChange = classifyWordPascal(styler.GetStartSegment(), i - 1, keywords, styler); + state = SCE_C_DEFAULT; + chNext = styler.SafeGetCharAt(i + 1); + if (ch == '{' && chNext != '$' && chNext != '&') { + state = SCE_C_COMMENT; + } else if (ch == '/' && chNext == '/') { + state = SCE_C_COMMENTLINE; + } else if (ch == '\"') { + state = SCE_C_STRING; + } else if (ch == '\'') { + state = SCE_C_CHARACTER; + } else if (isoperator(ch)) { + styler.ColourTo(i, SCE_C_OPERATOR); + } + levelCurrent+=levelChange; + } + } else { + if (state == SCE_C_PREPROCESSOR) { + if (ch=='}'){ + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + } else { + if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } + } + } else if (state == SCE_C_COMMENT) { + if (ch == '}' ) { + if (((i > styler.GetStartSegment() + 2) || ( + (initStyle == SCE_C_COMMENT) && + (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + } + } + } else if (state == SCE_C_COMMENTLINE) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i-1, state); + state = SCE_C_DEFAULT; + } + } else if (state == SCE_C_STRING) { + if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\"') { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + } else if (chNext == '\r' || chNext == '\n') { + styler.ColourTo(i-1, SCE_C_STRINGEOL); + state = SCE_C_STRINGEOL; + } + } else if (state == SCE_C_CHARACTER) { + if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { + styler.ColourTo(i-1, SCE_C_STRINGEOL); + state = SCE_C_STRINGEOL; + } else if (ch == '\\') { + if (chNext == '\"' || chNext == '\'' || chNext == '\\') { + i++; + ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + } + } else if (ch == '\'') { + styler.ColourTo(i, state); + state = SCE_C_DEFAULT; + } + } + } + chPrev = ch; + } + 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, levelCurrent | flagsNext); + styler.SetLevel(lineCurrent, levelPrev | flagsNext); + + } +} + +LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc); |