diff options
author | nyamatongwe <devnull@localhost> | 2007-06-12 03:57:34 +0000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2007-06-12 03:57:34 +0000 |
commit | c978704cfb581ebc98608fae61f5f10240786d20 (patch) | |
tree | 28cd5645266e6bd6b4c41fce1afe2e6be8f0d923 /src | |
parent | deae1c2bff572a88e63c57d10fb430bd260d9988 (diff) | |
download | scintilla-mirror-c978704cfb581ebc98608fae61f5f10240786d20.tar.gz |
PL/M and Progress lexers added.
Diffstat (limited to 'src')
-rw-r--r-- | src/KeyWords.cxx | 2 | ||||
-rw-r--r-- | src/LexPLM.cxx | 198 | ||||
-rw-r--r-- | src/LexProgress.cxx | 271 |
3 files changed, 471 insertions, 0 deletions
diff --git a/src/KeyWords.cxx b/src/KeyWords.cxx index 9c65b81d2..9921c4ccb 100644 --- a/src/KeyWords.cxx +++ b/src/KeyWords.cxx @@ -200,7 +200,9 @@ int Scintilla_LinkLexers() { LINK_LEXER(lmPerl); LINK_LEXER(lmPHP); LINK_LEXER(lmPHPSCRIPT); + LINK_LEXER(lmPLM); LINK_LEXER(lmPOV); + LINK_LEXER(lmProgress); LINK_LEXER(lmProps); LINK_LEXER(lmPS); LINK_LEXER(lmPureBasic); diff --git a/src/LexPLM.cxx b/src/LexPLM.cxx new file mode 100644 index 000000000..604850fbe --- /dev/null +++ b/src/LexPLM.cxx @@ -0,0 +1,198 @@ +// Copyright (c) 1990-2007, Scientific Toolworks, Inc. +// Author: Jason Haslam +// 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 "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" +#include "StyleContext.h" + +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + +static void GetRange(unsigned int start, + unsigned int end, + Accessor &styler, + char *s, + unsigned int len) { + unsigned int i = 0; + while ((i < end - start + 1) && (i < len-1)) { + s[i] = static_cast<char>(tolower(styler[start + i])); + i++; + } + s[i] = '\0'; +} + +static void ColourisePlmDoc(unsigned int startPos, + int length, + int initStyle, + WordList *keywordlists[], + Accessor &styler) +{ + unsigned int endPos = startPos + length; + int state = initStyle; + + styler.StartAt(startPos); + styler.StartSegment(startPos); + + for (unsigned int i = startPos; i < endPos; i++) { + char ch = styler.SafeGetCharAt(i); + char chNext = styler.SafeGetCharAt(i + 1); + + if (state == SCE_PLM_DEFAULT) { + if (ch == '/' && chNext == '*') { + styler.ColourTo(i - 1, state); + state = SCE_PLM_COMMENT; + } else if (ch == '\'') { + styler.ColourTo(i - 1, state); + state = SCE_PLM_STRING; + } else if (isdigit(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_PLM_NUMBER; + } else if (isalpha(ch)) { + styler.ColourTo(i - 1, state); + state = SCE_PLM_IDENTIFIER; + } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || + ch == '=' || ch == '<' || ch == '>' || ch == ':') { + styler.ColourTo(i - 1, state); + state = SCE_PLM_OPERATOR; + } else if (ch == '$') { + styler.ColourTo(i - 1, state); + state = SCE_PLM_CONTROL; + } + } else if (state == SCE_PLM_COMMENT) { + if (ch == '*' && chNext == '/') { + i++; + styler.ColourTo(i, state); + state = SCE_PLM_DEFAULT; + } + } else if (state == SCE_PLM_STRING) { + if (ch == '\'') { + if (chNext == '\'') { + i++; + } else { + styler.ColourTo(i, state); + state = SCE_PLM_DEFAULT; + } + } + } else if (state == SCE_PLM_NUMBER) { + if (!isdigit(ch) && !isalpha(ch) && ch != '$') { + i--; + styler.ColourTo(i, state); + state = SCE_PLM_DEFAULT; + } + } else if (state == SCE_PLM_IDENTIFIER) { + if (!isdigit(ch) && !isalpha(ch) && ch != '$') { + // Get the entire identifier. + char word[1024]; + int segmentStart = styler.GetStartSegment(); + GetRange(segmentStart, i - 1, styler, word, sizeof(word)); + + i--; + if (keywordlists[0]->InList(word)) + styler.ColourTo(i, SCE_PLM_KEYWORD); + else + styler.ColourTo(i, state); + state = SCE_PLM_DEFAULT; + } + } else if (state == SCE_PLM_OPERATOR) { + if (ch != '=' && ch != '>') { + i--; + styler.ColourTo(i, state); + state = SCE_PLM_DEFAULT; + } + } else if (state == SCE_PLM_CONTROL) { + if (ch == '\r' || ch == '\n') { + styler.ColourTo(i - 1, state); + state = SCE_PLM_DEFAULT; + } + } + } + styler.ColourTo(endPos - 1, state); +} + +static void FoldPlmDoc(unsigned int startPos, + int length, + int initStyle, + WordList *[], + Accessor &styler) +{ + bool foldComment = styler.GetPropertyInt("fold.comment") != 0; + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + unsigned int endPos = startPos + length; + int visibleChars = 0; + int lineCurrent = styler.GetLine(startPos); + int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; + int levelCurrent = levelPrev; + char chNext = styler[startPos]; + int styleNext = styler.StyleAt(startPos); + int style = initStyle; + int startKeyword = 0; + + for (unsigned int i = startPos; i < endPos; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + int stylePrev = style; + style = styleNext; + styleNext = styler.StyleAt(i + 1); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + + if (stylePrev != SCE_PLM_KEYWORD && style == SCE_PLM_KEYWORD) + startKeyword = i; + + if (style == SCE_PLM_KEYWORD && styleNext != SCE_PLM_KEYWORD) { + char word[1024]; + GetRange(startKeyword, i, styler, word, sizeof(word)); + + if (strcmp(word, "procedure") == 0 || strcmp(word, "do") == 0) + levelCurrent++; + else if (strcmp(word, "end") == 0) + levelCurrent--; + } + + if (foldComment) { + if (stylePrev != SCE_PLM_COMMENT && style == SCE_PLM_COMMENT) + levelCurrent++; + else if (stylePrev == SCE_PLM_COMMENT && style != SCE_PLM_COMMENT) + 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++; + } + + int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; + styler.SetLevel(lineCurrent, levelPrev | flagsNext); +} + +static const char *const plmWordListDesc[] = { + "Keywords", + 0 +}; + +LexerModule lmPLM(SCLEX_PLM, ColourisePlmDoc, "PL/M", FoldPlmDoc, plmWordListDesc); diff --git a/src/LexProgress.cxx b/src/LexProgress.cxx new file mode 100644 index 000000000..3b3a44541 --- /dev/null +++ b/src/LexProgress.cxx @@ -0,0 +1,271 @@ +// Scintilla source code edit control +/** @file LexProgress.cxx + ** Lexer for Progress 4GL. + ** Based on LexCPP.cxx of Neil Hodgson <neilh@scintilla.org> + **/ +// Copyright 2006-2007 by Yuval Papish <Yuval@YuvCom.com> +// The License.txt file describes the conditions under which this software may be distributed. + +/** TODO: +WebSpeed support in html lexer +Support "end triggers" expression of the triggers phrase +change lmPS to lmProgress +Support more than 6 comments levels +**/ +#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 "StyleContext.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + +static inline bool IsAWordChar(int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '_'); +} + +static inline bool IsAWordStart(int ch) { + return (ch < 0x80) && (isalpha(ch) || ch == '_'); +} + +enum SentenceStart { SetSentenceStart = 0xf, ResetSentenceStart = 0x10}; // true -> bit = 0 + +static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + + WordList &keywords1 = *keywordlists[0]; + WordList &keywords2 = *keywordlists[1]; + WordList &keywords3 = *keywordlists[2]; + //WordList &keywords4 = *keywordlists[3]; + //WordList &keywords5 = *keywordlists[4]; + + int visibleChars = 0; + int mask; + + StyleContext sc(startPos, length, initStyle, styler); + + for (; sc.More(); sc.Forward()) { + + if (sc.atLineStart) { + // Reset states to begining of colourise so no surprises + // if different sets of lines lexed. + visibleChars = 0; + } + + // Handle line continuation generically. + if (sc.ch == '~') { + // Skip whitespace between ~ and EOL + /* do { + sc.Forward(); + } */ + while ((sc.chNext == ' ' || sc.chNext == '\t') ) { + sc.Forward(); + sc.More(); + } + if (sc.chNext == '\n' || sc.chNext == '\r') { + sc.Forward(); + if (sc.ch == '\r' && sc.chNext == '\n') { + sc.Forward(); + } + sc.Forward(); + continue; + } + } + // Determine if a new state should be terminated. + mask = sc.state & 0x10; + switch (sc.state & 0xf) { + case SCE_4GL_OPERATOR: + sc.SetState(SCE_4GL_DEFAULT | mask); + break; + case SCE_4GL_NUMBER: + if (!(IsADigit(sc.ch))) { + sc.SetState(SCE_4GL_DEFAULT | mask); + } + break; + case SCE_4GL_IDENTIFIER: + if (!IsAWordChar(sc.ch) && sc.ch != '-') { + char s[1000]; + sc.GetCurrentLowered(s, sizeof(s)); + if (((sc.state & 0x10) == 0) && keywords2.InList(s) || keywords3.InList(s)) { + sc.ChangeState(SCE_4GL_BLOCK | ResetSentenceStart); + } + else if (keywords1.InList(s)) { + if ((s[0] == 'e' && s[1] =='n' && s[2] == 'd' && !isalnum(s[3]) && s[3] != '-') || + (s[0] == 'f' && s[1] =='o' && s[2] == 'r' && s[3] == 'w' && s[4] =='a' && s[5] == 'r' && s[6] == 'd'&& !isalnum(s[7]))) { + sc.ChangeState(SCE_4GL_END | ResetSentenceStart); + } + else if ((s[0] == 'e' && s[1] =='l' && s[2] == 's' && s[3] == 'e') || + (s[0] == 't' && s[1] =='h' && s[2] == 'e' && s[3] == 'n')) { + sc.ChangeState(SCE_4GL_WORD & SetSentenceStart); + } + else { + sc.ChangeState(SCE_4GL_WORD | ResetSentenceStart); + } + } + sc.SetState(SCE_4GL_DEFAULT | (sc.state & 0x10)); + } + break; + case SCE_4GL_PREPROCESSOR: + if (sc.atLineStart) { + sc.SetState(SCE_4GL_DEFAULT & SetSentenceStart); + } else if (sc.ch == '*' && sc.chNext == '/') { + sc.ForwardSetState(SCE_4GL_DEFAULT | mask); + } + break; + case SCE_4GL_STRING: + if (sc.ch == '\"') { + sc.ForwardSetState(SCE_4GL_DEFAULT | mask); + } + break; + case SCE_4GL_CHARACTER: + if (sc.ch == '\'') { + sc.ForwardSetState(SCE_4GL_DEFAULT | mask); + } + break; + default: + if ((sc.state & 0xf) >= SCE_4GL_COMMENT1) { + if (sc.ch == '*' && sc.chNext == '/') { + sc.Forward(); + if ((sc.state & 0xf) == SCE_4GL_COMMENT1) { + sc.ForwardSetState(SCE_4GL_DEFAULT | mask); + } + else + sc.SetState((sc.state & 0x1f) - 1); + } else if (sc.ch == '/' && sc.chNext == '*') { + sc.Forward(); + sc.SetState((sc.state & 0x1f) + 1); + } + } + } + + // Determine if a new state should be entered. + mask = sc.state & 0x10; + if ((sc.state & 0xf) == SCE_4GL_DEFAULT) { + if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { + sc.SetState(SCE_4GL_NUMBER | ResetSentenceStart); + } else if (IsAWordStart(sc.ch) || (sc.ch == '@')) { + sc.SetState(SCE_4GL_IDENTIFIER | mask); + } else if (sc.ch == '/' && sc.chNext == '*') { + sc.SetState(SCE_4GL_COMMENT1 | mask); + sc.Forward(); + } else if (sc.ch == '\"') { + sc.SetState(SCE_4GL_STRING | ResetSentenceStart); + } else if (sc.ch == '\'') { + sc.SetState(SCE_4GL_CHARACTER | ResetSentenceStart); + } else if (sc.ch == '&' && visibleChars == 0 && ((sc.state & 0x10) == 0)) { + sc.SetState(SCE_4GL_PREPROCESSOR | ResetSentenceStart); + // Skip whitespace between & and preprocessor word + do { + sc.Forward(); + } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); + // Handle syntactical line termination + } else if ((sc.ch == '.' || sc.ch == ':' || sc.ch == '}') && (sc.chNext == ' ' || sc.chNext == '\t' || sc.chNext == '\n' || sc.chNext == '\r')) { + sc.SetState(sc.state & SetSentenceStart); + } else if (isoperator(static_cast<char>(sc.ch))) { + if (sc.ch == ':') + sc.SetState(SCE_4GL_OPERATOR & SetSentenceStart); + else + sc.SetState(SCE_4GL_OPERATOR | ResetSentenceStart); + } + } + + if (!IsASpace(sc.ch)) { + visibleChars++; + } + } + sc.Complete(); +} + +static bool IsStreamCommentStyle(int style) { + return (style & 0xf) >= SCE_4GL_COMMENT1 ; +} + +// Store both the current line's fold level and the next lines in the +// level store to make it easy to pick up with each increment +// and to make it possible to fiddle the current level for "} else {". +static void FoldNoBox4glDoc(unsigned int startPos, int length, int initStyle, + Accessor &styler) { + bool foldComment = styler.GetPropertyInt("fold.comment") != 0; + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; + unsigned int endPos = startPos + length; + int visibleChars = 0; + int lineCurrent = styler.GetLine(startPos); + int levelCurrent = SC_FOLDLEVELBASE; + if (lineCurrent > 0) + levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; + int levelMinCurrent = levelCurrent; + int levelNext = levelCurrent; + char chNext = static_cast<char>(tolower(styler[startPos])); + int styleNext = styler.StyleAt(startPos); + int style = initStyle; + for (unsigned int i = startPos; i < endPos; i++) { + char ch = chNext; + chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1))); + int stylePrev = style; + style = styleNext; + styleNext = styler.StyleAt(i + 1); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + if (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--; + } + } + else if ((style & 0xf) == SCE_4GL_BLOCK && !isalnum(chNext)) { + levelNext++; + } + else if ((style & 0xf) == SCE_4GL_END && (ch == 'e' || ch == 'f')) { + levelNext--; + } + if (atEOL) { + int levelUse = levelCurrent; + if (foldAtElse) { + levelUse = levelMinCurrent; + } + int lev = levelUse | levelNext << 16; + if (visibleChars == 0 && foldCompact) + lev |= SC_FOLDLEVELWHITEFLAG; + if (levelUse < levelNext) + lev |= SC_FOLDLEVELHEADERFLAG; + if (lev != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, lev); + } + lineCurrent++; + levelCurrent = levelNext; + levelMinCurrent = levelCurrent; + visibleChars = 0; + } + if (!isspacechar(ch)) + visibleChars++; + } +} + +static void Fold4glDoc(unsigned int startPos, int length, int initStyle, WordList *[], + Accessor &styler) { + FoldNoBox4glDoc(startPos, length, initStyle, styler); +} + +static const char * const FglWordLists[] = { + "Primary keywords and identifiers", + "Secondary keywords and identifiers", + "Documentation comment keywords", + "Unused", + "Global classes and typedefs", + 0, + }; + +LexerModule lmProgress(SCLEX_PS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists); |