]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexProgress.cxx
1 // Scintilla source code edit control
2 /** @file LexProgress.cxx
3 ** Lexer for Progress 4GL.
4 ** Based on LexCPP.cxx of Neil Hodgson <neilh@scintilla.org>
6 // Copyright 2006-2007 by Yuval Papish <Yuval@YuvCom.com>
7 // The License.txt file describes the conditions under which this software may be distributed.
10 WebSpeed support in html lexer
11 Support "end triggers" expression of the triggers phrase
12 change lmPS to lmProgress
13 Support more than 6 comments levels
25 #include "StyleContext.h"
27 #include "Scintilla.h"
31 using namespace Scintilla
;
34 static inline bool IsAWordChar(int ch
) {
35 return (ch
< 0x80) && (isalnum(ch
) || ch
== '_');
38 static inline bool IsAWordStart(int ch
) {
39 return (ch
< 0x80) && (isalpha(ch
) || ch
== '_');
42 enum SentenceStart
{ SetSentenceStart
= 0xf, ResetSentenceStart
= 0x10}; // true -> bit = 0
44 static void Colourise4glDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
47 WordList
&keywords1
= *keywordlists
[0];
48 WordList
&keywords2
= *keywordlists
[1];
49 WordList
&keywords3
= *keywordlists
[2];
50 //WordList &keywords4 = *keywordlists[3];
51 //WordList &keywords5 = *keywordlists[4];
56 StyleContext
sc(startPos
, length
, initStyle
, styler
);
58 for (; sc
.More(); sc
.Forward()) {
61 // Reset states to begining of colourise so no surprises
62 // if different sets of lines lexed.
66 // Handle line continuation generically.
68 // Skip whitespace between ~ and EOL
72 while ((sc
.chNext
== ' ' || sc
.chNext
== '\t') ) {
76 if (sc
.chNext
== '\n' || sc
.chNext
== '\r') {
78 if (sc
.ch
== '\r' && sc
.chNext
== '\n') {
85 // Determine if a new state should be terminated.
86 mask
= sc
.state
& 0x10;
87 switch (sc
.state
& 0xf) {
88 case SCE_4GL_OPERATOR
:
89 sc
.SetState(SCE_4GL_DEFAULT
| mask
);
92 if (!(IsADigit(sc
.ch
))) {
93 sc
.SetState(SCE_4GL_DEFAULT
| mask
);
96 case SCE_4GL_IDENTIFIER
:
97 if (!IsAWordChar(sc
.ch
) && sc
.ch
!= '-') {
99 sc
.GetCurrentLowered(s
, sizeof(s
));
100 if (((sc
.state
& 0x10) == 0) && keywords2
.InList(s
) || keywords3
.InList(s
)) {
101 sc
.ChangeState(SCE_4GL_BLOCK
| ResetSentenceStart
);
103 else if (keywords1
.InList(s
)) {
104 if ((s
[0] == 'e' && s
[1] =='n' && s
[2] == 'd' && !isalnum(s
[3]) && s
[3] != '-') ||
105 (s
[0] == 'f' && s
[1] =='o' && s
[2] == 'r' && s
[3] == 'w' && s
[4] =='a' && s
[5] == 'r' && s
[6] == 'd'&& !isalnum(s
[7]))) {
106 sc
.ChangeState(SCE_4GL_END
| ResetSentenceStart
);
108 else if ((s
[0] == 'e' && s
[1] =='l' && s
[2] == 's' && s
[3] == 'e') ||
109 (s
[0] == 't' && s
[1] =='h' && s
[2] == 'e' && s
[3] == 'n')) {
110 sc
.ChangeState(SCE_4GL_WORD
& SetSentenceStart
);
113 sc
.ChangeState(SCE_4GL_WORD
| ResetSentenceStart
);
116 sc
.SetState(SCE_4GL_DEFAULT
| (sc
.state
& 0x10));
119 case SCE_4GL_PREPROCESSOR
:
120 if (sc
.atLineStart
) {
121 sc
.SetState(SCE_4GL_DEFAULT
& SetSentenceStart
);
122 } else if (sc
.ch
== '*' && sc
.chNext
== '/') {
123 sc
.ForwardSetState(SCE_4GL_DEFAULT
| mask
);
128 sc
.ForwardSetState(SCE_4GL_DEFAULT
| mask
);
131 case SCE_4GL_CHARACTER
:
133 sc
.ForwardSetState(SCE_4GL_DEFAULT
| mask
);
137 if ((sc
.state
& 0xf) >= SCE_4GL_COMMENT1
) {
138 if (sc
.ch
== '*' && sc
.chNext
== '/') {
140 if ((sc
.state
& 0xf) == SCE_4GL_COMMENT1
) {
141 sc
.ForwardSetState(SCE_4GL_DEFAULT
| mask
);
144 sc
.SetState((sc
.state
& 0x1f) - 1);
145 } else if (sc
.ch
== '/' && sc
.chNext
== '*') {
147 sc
.SetState((sc
.state
& 0x1f) + 1);
152 // Determine if a new state should be entered.
153 mask
= sc
.state
& 0x10;
154 if ((sc
.state
& 0xf) == SCE_4GL_DEFAULT
) {
155 if (IsADigit(sc
.ch
) || (sc
.ch
== '.' && IsADigit(sc
.chNext
))) {
156 sc
.SetState(SCE_4GL_NUMBER
| ResetSentenceStart
);
157 } else if (IsAWordStart(sc
.ch
) || (sc
.ch
== '@')) {
158 sc
.SetState(SCE_4GL_IDENTIFIER
| mask
);
159 } else if (sc
.ch
== '/' && sc
.chNext
== '*') {
160 sc
.SetState(SCE_4GL_COMMENT1
| mask
);
162 } else if (sc
.ch
== '\"') {
163 sc
.SetState(SCE_4GL_STRING
| ResetSentenceStart
);
164 } else if (sc
.ch
== '\'') {
165 sc
.SetState(SCE_4GL_CHARACTER
| ResetSentenceStart
);
166 } else if (sc
.ch
== '&' && visibleChars
== 0 && ((sc
.state
& 0x10) == 0)) {
167 sc
.SetState(SCE_4GL_PREPROCESSOR
| ResetSentenceStart
);
168 // Skip whitespace between & and preprocessor word
171 } while ((sc
.ch
== ' ' || sc
.ch
== '\t') && sc
.More());
172 // Handle syntactical line termination
173 } else if ((sc
.ch
== '.' || sc
.ch
== ':' || sc
.ch
== '}') && (sc
.chNext
== ' ' || sc
.chNext
== '\t' || sc
.chNext
== '\n' || sc
.chNext
== '\r')) {
174 sc
.SetState(sc
.state
& SetSentenceStart
);
175 } else if (isoperator(static_cast<char>(sc
.ch
))) {
177 sc
.SetState(SCE_4GL_OPERATOR
& SetSentenceStart
);
179 sc
.SetState(SCE_4GL_OPERATOR
| ResetSentenceStart
);
183 if (!IsASpace(sc
.ch
)) {
190 static bool IsStreamCommentStyle(int style
) {
191 return (style
& 0xf) >= SCE_4GL_COMMENT1
;
194 // Store both the current line's fold level and the next lines in the
195 // level store to make it easy to pick up with each increment
196 // and to make it possible to fiddle the current level for "} else {".
197 static void FoldNoBox4glDoc(unsigned int startPos
, int length
, int initStyle
,
199 bool foldComment
= styler
.GetPropertyInt("fold.comment") != 0;
200 bool foldCompact
= styler
.GetPropertyInt("fold.compact", 1) != 0;
201 bool foldAtElse
= styler
.GetPropertyInt("fold.at.else", 0) != 0;
202 unsigned int endPos
= startPos
+ length
;
203 int visibleChars
= 0;
204 int lineCurrent
= styler
.GetLine(startPos
);
205 int levelCurrent
= SC_FOLDLEVELBASE
;
207 levelCurrent
= styler
.LevelAt(lineCurrent
-1) >> 16;
208 int levelMinCurrent
= levelCurrent
;
209 int levelNext
= levelCurrent
;
210 char chNext
= static_cast<char>(tolower(styler
[startPos
]));
211 int styleNext
= styler
.StyleAt(startPos
);
212 int style
= initStyle
;
213 for (unsigned int i
= startPos
; i
< endPos
; i
++) {
215 chNext
= static_cast<char>(tolower(styler
.SafeGetCharAt(i
+ 1)));
216 int stylePrev
= style
;
218 styleNext
= styler
.StyleAt(i
+ 1);
219 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
220 if (foldComment
&& IsStreamCommentStyle(style
)) {
221 if (!IsStreamCommentStyle(stylePrev
)) {
223 } else if (!IsStreamCommentStyle(styleNext
)) { // && !atEOL) {
224 // Comments don't end at end of line and the next character may be unstyled.
228 else if ((style
& 0xf) == SCE_4GL_BLOCK
&& !isalnum(chNext
)) {
231 else if ((style
& 0xf) == SCE_4GL_END
&& (ch
== 'e' || ch
== 'f')) {
235 int levelUse
= levelCurrent
;
237 levelUse
= levelMinCurrent
;
239 int lev
= levelUse
| levelNext
<< 16;
240 if (visibleChars
== 0 && foldCompact
)
241 lev
|= SC_FOLDLEVELWHITEFLAG
;
242 if (levelUse
< levelNext
)
243 lev
|= SC_FOLDLEVELHEADERFLAG
;
244 if (lev
!= styler
.LevelAt(lineCurrent
)) {
245 styler
.SetLevel(lineCurrent
, lev
);
248 levelCurrent
= levelNext
;
249 levelMinCurrent
= levelCurrent
;
252 if (!isspacechar(ch
))
257 static void Fold4glDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*[],
259 FoldNoBox4glDoc(startPos
, length
, initStyle
, styler
);
262 static const char * const FglWordLists
[] = {
263 "Primary keywords and identifiers",
264 "Secondary keywords and identifiers",
265 "Documentation comment keywords",
267 "Global classes and typedefs",
271 LexerModule
lmProgress(SCLEX_PS
, Colourise4glDoc
, "progress", Fold4glDoc
, FglWordLists
);