]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/stc/scintilla/src/LexEScript.cxx
Updated wxSTC's copy of Scintilla to version 1.61
[wxWidgets.git] / contrib / src / stc / scintilla / src / LexEScript.cxx
CommitLineData
e14d10b0
RD
1// Scintilla source code edit control
2/** @file LexESCRIPT.cxx
3 ** Lexer for ESCRIPT
4 **/
5// Copyright 2003 by Patrizio Bekerle (patrizio@bekerle.com)
6
7#include <stdlib.h>
8#include <string.h>
9#include <ctype.h>
10#include <stdio.h>
11#include <stdarg.h>
12
13#include "Platform.h"
14
15#include "PropSet.h"
16#include "Accessor.h"
17#include "StyleContext.h"
18#include "KeyWords.h"
19#include "Scintilla.h"
20#include "SciLexer.h"
21
22
23
24static inline bool IsAWordChar(const int ch) {
25 return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
26}
27
28static inline bool IsAWordStart(const int ch) {
29 return (ch < 0x80) && (isalnum(ch) || ch == '_');
30}
31
32
33
34static void ColouriseESCRIPTDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
35 Accessor &styler) {
36
37 WordList &keywords = *keywordlists[0];
38 WordList &keywords2 = *keywordlists[1];
39 WordList &keywords3 = *keywordlists[2];
40
41 // Do not leak onto next line
42 /*if (initStyle == SCE_ESCRIPT_STRINGEOL)
43 initStyle = SCE_ESCRIPT_DEFAULT;*/
44
45 StyleContext sc(startPos, length, initStyle, styler);
46
47 bool caseSensitive = styler.GetPropertyInt("escript.case.sensitive", 0) != 0;
48
49 for (; sc.More(); sc.Forward()) {
50
51 /*if (sc.atLineStart && (sc.state == SCE_ESCRIPT_STRING)) {
52 // Prevent SCE_ESCRIPT_STRINGEOL from leaking back to previous line
53 sc.SetState(SCE_ESCRIPT_STRING);
54 }*/
55
56 // Handle line continuation generically.
57 if (sc.ch == '\\') {
58 if (sc.chNext == '\n' || sc.chNext == '\r') {
59 sc.Forward();
60 if (sc.ch == '\r' && sc.chNext == '\n') {
61 sc.Forward();
62 }
63 continue;
64 }
65 }
66
67 // Determine if the current state should terminate.
68 if (sc.state == SCE_ESCRIPT_OPERATOR || sc.state == SCE_ESCRIPT_BRACE) {
69 sc.SetState(SCE_ESCRIPT_DEFAULT);
70 } else if (sc.state == SCE_ESCRIPT_NUMBER) {
71 if (!IsADigit(sc.ch) || sc.ch != '.') {
72 sc.SetState(SCE_ESCRIPT_DEFAULT);
73 }
74 } else if (sc.state == SCE_ESCRIPT_IDENTIFIER) {
75 if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
76 char s[100];
77 if (caseSensitive) {
78 sc.GetCurrent(s, sizeof(s));
79 } else {
80 sc.GetCurrentLowered(s, sizeof(s));
81 }
82
83// sc.GetCurrentLowered(s, sizeof(s));
84
85 if (keywords.InList(s)) {
86 sc.ChangeState(SCE_ESCRIPT_WORD);
87 } else if (keywords2.InList(s)) {
88 sc.ChangeState(SCE_ESCRIPT_WORD2);
89 } else if (keywords3.InList(s)) {
90 sc.ChangeState(SCE_ESCRIPT_WORD3);
91 // sc.state = SCE_ESCRIPT_IDENTIFIER;
92 }
93 sc.SetState(SCE_ESCRIPT_DEFAULT);
94 }
95 } else if (sc.state == SCE_ESCRIPT_COMMENT) {
96 if (sc.Match('*', '/')) {
97 sc.Forward();
98 sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
99 }
100 } else if (sc.state == SCE_ESCRIPT_COMMENTDOC) {
101 if (sc.Match('*', '/')) {
102 sc.Forward();
103 sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
104 }
105 } else if (sc.state == SCE_ESCRIPT_COMMENTLINE) {
106 if (sc.atLineEnd) {
107 sc.SetState(SCE_ESCRIPT_DEFAULT);
108 }
109 } else if (sc.state == SCE_ESCRIPT_STRING) {
110 if (sc.ch == '\\') {
111 if (sc.chNext == '\"' || sc.chNext == '\\') {
112 sc.Forward();
113 }
114 } else if (sc.ch == '\"') {
115 sc.ForwardSetState(SCE_ESCRIPT_DEFAULT);
116 }
117 }
118
119 // Determine if a new state should be entered.
120 if (sc.state == SCE_ESCRIPT_DEFAULT) {
121 if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
122 sc.SetState(SCE_ESCRIPT_NUMBER);
123 } else if (IsAWordStart(sc.ch) || (sc.ch == '#')) {
124 sc.SetState(SCE_ESCRIPT_IDENTIFIER);
125 } else if (sc.Match('/', '*')) {
126 sc.SetState(SCE_ESCRIPT_COMMENT);
127 sc.Forward(); // Eat the * so it isn't used for the end of the comment
128 } else if (sc.Match('/', '/')) {
129 sc.SetState(SCE_ESCRIPT_COMMENTLINE);
130 } else if (sc.ch == '\"') {
131 sc.SetState(SCE_ESCRIPT_STRING);
132 //} else if (isoperator(static_cast<char>(sc.ch))) {
133 } else if (sc.ch == '+' || sc.ch == '-' || sc.ch == '*' || sc.ch == '/' || sc.ch == '=' || sc.ch == '<' || sc.ch == '>' || sc.ch == '&' || sc.ch == '|' || sc.ch == '!' || sc.ch == '?' || sc.ch == ':') {
134 sc.SetState(SCE_ESCRIPT_OPERATOR);
135 } else if (sc.ch == '{' || sc.ch == '}') {
136 sc.SetState(SCE_ESCRIPT_BRACE);
137 }
138 }
139
140 }
141 sc.Complete();
142}
143
144
145static int classifyFoldPointESCRIPT(const char* s, const char* prevWord) {
146 int lev = 0;
147 if (strcmp(prevWord, "end") == 0) return lev;
148 if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0)
149 return -1;
150
151 if (strcmp(s, "for") == 0 || strcmp(s, "foreach") == 0
152 || strcmp(s, "program") == 0 || strcmp(s, "function") == 0
153 || strcmp(s, "while") == 0 || strcmp(s, "case") == 0
154 || strcmp(s, "if") == 0 ) {
155 lev = 1;
156 } else if ( strcmp(s, "endfor") == 0 || strcmp(s, "endforeach") == 0
157 || strcmp(s, "endprogram") == 0 || strcmp(s, "endfunction") == 0
158 || strcmp(s, "endwhile") == 0 || strcmp(s, "endcase") == 0
159 || strcmp(s, "endif") == 0 ) {
160 lev = -1;
161 }
162
163 return lev;
164}
165
166
167static bool IsStreamCommentStyle(int style) {
168 return style == SCE_ESCRIPT_COMMENT ||
169 style == SCE_ESCRIPT_COMMENTDOC ||
170 style == SCE_ESCRIPT_COMMENTLINE;
171}
172
173static void FoldESCRIPTDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
174 //~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
175 // Do not know how to fold the comment at the moment.
176 bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
177 bool foldComment = true;
178 unsigned int endPos = startPos + length;
179 int visibleChars = 0;
180 int lineCurrent = styler.GetLine(startPos);
181 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
182 int levelCurrent = levelPrev;
183 char chNext = styler[startPos];
184 int styleNext = styler.StyleAt(startPos);
185 int style = initStyle;
186
187 int lastStart = 0;
188 char prevWord[32] = "";
189
190 for (unsigned int i = startPos; i < endPos; i++) {
191 char ch = chNext;
192 chNext = styler.SafeGetCharAt(i + 1);
193 int stylePrev = style;
194 style = styleNext;
195 styleNext = styler.StyleAt(i + 1);
196 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
197
88a8b04e 198
e14d10b0
RD
199 if (foldComment && IsStreamCommentStyle(style)) {
200 if (!IsStreamCommentStyle(stylePrev)) {
201 levelCurrent++;
202 } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
203 // Comments don't end at end of line and the next character may be unstyled.
204 levelCurrent--;
205 }
206 }
207
208 if (foldComment && (style == SCE_ESCRIPT_COMMENTLINE)) {
209 if ((ch == '/') && (chNext == '/')) {
210 char chNext2 = styler.SafeGetCharAt(i + 2);
211 if (chNext2 == '{') {
212 levelCurrent++;
213 } else if (chNext2 == '}') {
214 levelCurrent--;
215 }
216 }
217 }
218
219 if (stylePrev == SCE_ESCRIPT_DEFAULT && style == SCE_ESCRIPT_WORD3)
220 {
221 // Store last word start point.
222 lastStart = i;
223 }
224
225 if (style == SCE_ESCRIPT_WORD3) {
226 if(iswordchar(ch) && !iswordchar(chNext)) {
227 char s[32];
228 unsigned int j;
229 for(j = 0; ( j < 31 ) && ( j < i-lastStart+1 ); j++) {
230 s[j] = static_cast<char>(tolower(styler[lastStart + j]));
231 }
232 s[j] = '\0';
233 levelCurrent += classifyFoldPointESCRIPT(s, prevWord);
234 strcpy(prevWord, s);
235 }
236 }
237 if (atEOL) {
238 int lev = levelPrev;
239 if (visibleChars == 0 && foldCompact)
240 lev |= SC_FOLDLEVELWHITEFLAG;
241 if ((levelCurrent > levelPrev) && (visibleChars > 0))
242 lev |= SC_FOLDLEVELHEADERFLAG;
243 if (lev != styler.LevelAt(lineCurrent)) {
244 styler.SetLevel(lineCurrent, lev);
245 }
246 lineCurrent++;
247 levelPrev = levelCurrent;
248 visibleChars = 0;
249 strcpy(prevWord, "");
250 }
251
252 if (!isspacechar(ch))
253 visibleChars++;
254 }
255
256 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
257 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
258 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
259}
260
261
262
263static const char * const ESCRIPTWordLists[] = {
264 "Primary keywords and identifiers",
265 "Intrinsic functions",
266 "Extended and user defined functions",
267 0,
268};
269
270LexerModule lmESCRIPT(SCLEX_ESCRIPT, ColouriseESCRIPTDoc, "escript", FoldESCRIPTDoc, ESCRIPTWordLists);