]> git.saurik.com Git - wxWidgets.git/blame - src/stc/scintilla/src/LexLua.cxx
fix for a typo (== instead of =)
[wxWidgets.git] / src / stc / scintilla / src / LexLua.cxx
CommitLineData
65ec6247
RD
1// Scintilla source code edit control
2/** @file LexLua.cxx
3 ** Lexer for Lua language.
4 **
5 ** Written by Paul Winwood.
6 ** Folder by Alexey Yutkin.
7 **/
d134f170
RD
8
9#include <stdlib.h>
10#include <string.h>
11#include <ctype.h>
12#include <stdarg.h>
13#include <stdio.h>
14#include <fcntl.h>
15
16#include "Platform.h"
17
18#include "PropSet.h"
19#include "Accessor.h"
20#include "KeyWords.h"
21#include "Scintilla.h"
22#include "SciLexer.h"
23
65ec6247
RD
24inline bool isLuaOperator(char ch) {
25 if (isalnum(ch))
26 return false;
27 // '.' left out as it is used to make up numbers
28 if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
29 ch == '(' || ch == ')' || ch == '=' ||
30 ch == '{' || ch == '}' || ch == '~' ||
31 ch == '[' || ch == ']' || ch == ';' ||
32 ch == '<' || ch == '>' || ch == ',' ||
33 ch == '.' || ch == '^' || ch == '%' || ch == ':')
34 return true;
35 return false;
36}
37
38static void classifyWordLua(unsigned int start,
39 unsigned int end,
40 WordList &keywords,
41 Accessor &styler) {
42 char s[100];
43 bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');
44
45 for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
46 s[i] = styler[start + i];
47 s[i + 1] = '\0';
48 }
d134f170 49
65ec6247
RD
50 char chAttr = SCE_LUA_IDENTIFIER;
51
52 if (wordIsNumber)
53 chAttr = SCE_LUA_NUMBER;
54 else {
55 if (keywords.InList(s)) {
56 chAttr = SCE_LUA_WORD;
57 }
58 }
59 styler.ColourTo(end, chAttr);
d134f170
RD
60}
61
65ec6247
RD
62static void ColouriseLuaDoc(unsigned int startPos,
63 int length,
64 int initStyle,
65 WordList *keywordlists[],
66 Accessor &styler) {
67
68 WordList &keywords = *keywordlists[0];
d134f170 69
65ec6247
RD
70 styler.StartAt(startPos);
71 styler.GetLine(startPos);
d134f170 72
65ec6247
RD
73 int state = initStyle;
74 char chPrev = ' ';
75 char chNext = styler[startPos];
76 unsigned int lengthDoc = startPos + length;
77 bool firstChar = true;
d134f170 78
65ec6247
RD
79 /* Must initialize the literalString level, if we are inside such a string.
80 * Note: this isn't enough, because literal strings can be nested,
81 * we should go back to see at what level we are...
82 */
83 int literalString = (initStyle == SCE_LUA_LITERALSTRING) ? 1 : 0;
d134f170 84
65ec6247
RD
85 styler.StartSegment(startPos);
86 for (unsigned int i = startPos; i <= lengthDoc; i++) {
87 char ch = chNext;
88 chNext = styler.SafeGetCharAt(i + 1);
d134f170 89
65ec6247
RD
90 if (styler.IsLeadByte(ch)) {
91 chNext = styler.SafeGetCharAt(i + 2);
92 chPrev = ' ';
93 i += 1;
94 continue;
95 }
96
97 if (state == SCE_LUA_STRINGEOL) {
98 if (ch != '\r' && ch != '\n') {
99 styler.ColourTo(i - 1, state);
100 state = SCE_LUA_DEFAULT;
101 }
102 }
103
104 if (state == SCE_LUA_LITERALSTRING && ch == '[' && chNext == '[') {
105 literalString++;
106 } else if (state == SCE_LUA_DEFAULT) {
107 if (ch == '-' && chNext == '-') {
108 styler.ColourTo(i - 1, state);
109 state = SCE_LUA_COMMENTLINE;
110 } else if (ch == '[' && chNext == '[') {
111 state = SCE_LUA_LITERALSTRING;
112 literalString = 1;
113 } else if (ch == '\"') {
114 styler.ColourTo(i - 1, state);
115 state = SCE_LUA_STRING;
116 } else if (ch == '\'') {
117 styler.ColourTo(i - 1, state);
118 state = SCE_LUA_CHARACTER;
119 } else if (ch == '$' && firstChar) {
120 styler.ColourTo(i - 1, state);
121 state = SCE_LUA_PREPROCESSOR;
122 } else if (ch == '#' && firstChar) // Should be only on the first line of the file! Cannot be tested here
123 {
124 styler.ColourTo(i - 1, state);
125 state = SCE_LUA_COMMENTLINE;
126 } else if (isLuaOperator(ch)) {
127 styler.ColourTo(i - 1, state);
128 styler.ColourTo(i, SCE_LUA_OPERATOR);
129 } else if (iswordstart(ch)) {
130 styler.ColourTo(i - 1, state);
131 state = SCE_LUA_WORD;
132 }
133 } else if (state == SCE_LUA_WORD) {
134 if (!iswordchar(ch)) {
135 classifyWordLua(styler.GetStartSegment(), i - 1, keywords, styler);
136 state = SCE_LUA_DEFAULT;
137 if (ch == '[' && chNext == '[') {
138 literalString = 1;
139 state = SCE_LUA_LITERALSTRING;
140 } else if (ch == '-' && chNext == '-') {
141 state = SCE_LUA_COMMENTLINE;
142 } else if (ch == '\"') {
143 state = SCE_LUA_STRING;
144 } else if (ch == '\'') {
145 state = SCE_LUA_CHARACTER;
146 } else if (ch == '$' && firstChar) {
147 state = SCE_LUA_PREPROCESSOR;
148 } else if (isLuaOperator(ch)) {
149 styler.ColourTo(i, SCE_LUA_OPERATOR);
150 }
151 } else if (ch == '.' && chNext == '.') {
152 classifyWordLua(styler.GetStartSegment(), i - 1, keywords, styler);
153 styler.ColourTo(i, SCE_LUA_OPERATOR);
154 state = SCE_LUA_DEFAULT;
155 }
156 } else {
157 if (state == SCE_LUA_LITERALSTRING) {
158 if (ch == ']' && (chPrev == ']') && (--literalString == 0)) {
159 styler.ColourTo(i, state);
160 state = SCE_LUA_DEFAULT;
161 }
162 } else if (state == SCE_LUA_PREPROCESSOR) {
163 if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
164 styler.ColourTo(i - 1, state);
165 state = SCE_LUA_DEFAULT;
166 }
167 } else if (state == SCE_LUA_COMMENTLINE) {
168 if (ch == '\r' || ch == '\n') {
169 styler.ColourTo(i - 1, state);
170 state = SCE_LUA_DEFAULT;
171 }
172 } else if (state == SCE_LUA_STRING) {
173 if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
174 styler.ColourTo(i - 1, state);
175 state = SCE_LUA_STRINGEOL;
176 } else if (ch == '\\') {
177 if (chNext == '\"' || chNext == '\\') {
178 i++;
179 ch = chNext;
180 chNext = styler.SafeGetCharAt(i + 1);
181 }
182 } else if (ch == '\"') {
183 styler.ColourTo(i, state);
184 state = SCE_LUA_DEFAULT;
185 i++;
186 ch = chNext;
187 chNext = styler.SafeGetCharAt(i + 1);
188 }
189 } else if (state == SCE_LUA_CHARACTER) {
190 if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
191 styler.ColourTo(i - 1, state);
192 state = SCE_LUA_STRINGEOL;
193 } else if (ch == '\\') {
194 if (chNext == '\'' || chNext == '\\') {
195 i++;
196 ch = chNext;
197 chNext = styler.SafeGetCharAt(i + 1);
198 }
199 } else if (ch == '\'') {
200 styler.ColourTo(i, state);
201 state = SCE_LUA_DEFAULT;
202 i++;
203 ch = chNext;
204 chNext = styler.SafeGetCharAt(i + 1);
205 }
206 }
207
208 if (state == SCE_LUA_DEFAULT) {
209 if (ch == '-' && chNext == '-') {
210 state = SCE_LUA_COMMENTLINE;
211 } else if (ch == '\"') {
212 state = SCE_LUA_STRING;
213 } else if (ch == '\'') {
214 state = SCE_LUA_CHARACTER;
215 } else if (ch == '$' && firstChar) {
216 state = SCE_LUA_PREPROCESSOR;
217 } else if (iswordstart(ch)) {
218 state = SCE_LUA_WORD;
219 } else if (isLuaOperator(ch)) {
220 styler.ColourTo(i, SCE_LUA_OPERATOR);
221 }
222 }
223 }
224 chPrev = ch;
225 firstChar = (ch == '\r' || ch == '\n');
226 }
227 styler.ColourTo(lengthDoc - 1, state);
228}
d134f170 229
65ec6247
RD
230static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
231 Accessor &styler) {
232 unsigned int lengthDoc = startPos + length;
233 int visibleChars = 0;
234 int lineCurrent = styler.GetLine(startPos);
235 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
236 int levelCurrent = levelPrev;
237 char chNext = styler[startPos];
238 int styleNext = styler.StyleAt(startPos);
239 char s[10];
240 for (unsigned int i = startPos; i < lengthDoc; i++) {
241 char ch = chNext;
242 chNext = styler.SafeGetCharAt(i + 1);
243 int style = styleNext;
244 styleNext = styler.StyleAt(i + 1);
245 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
246 if (style == SCE_LUA_WORD)
247 if ( ch == 'e' || ch == 't' || ch == 'd' || ch == 'f') {
248 for (unsigned int j = 0; j < 8; j++) {
249 if (!iswordchar(styler[i + j])) break;
250 s[j] = styler[i + j];
251 s[j + 1] = '\0';
252 }
d134f170 253
65ec6247
RD
254 if ((strcmp(s, "then") == 0) || (strcmp(s, "do") == 0)
255 || (strcmp(s, "function") == 0))
256 levelCurrent++;
257 if (strcmp(s, "end") == 0) levelCurrent--;
258 }
d134f170 259
65ec6247
RD
260 if (atEOL) {
261 int lev = levelPrev;
262 if (visibleChars == 0)
263 lev |= SC_FOLDLEVELWHITEFLAG;
264 if ((levelCurrent > levelPrev) && (visibleChars > 0))
265 lev |= SC_FOLDLEVELHEADERFLAG;
266 if (lev != styler.LevelAt(lineCurrent)) {
267 styler.SetLevel(lineCurrent, lev);
268 }
269 lineCurrent++;
270 levelPrev = levelCurrent;
271 visibleChars = 0;
272 }
273 if (!isspacechar(ch))
274 visibleChars++;
275 }
276 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
277 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
278 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
d134f170
RD
279}
280
65ec6247 281LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc);