]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexSmalltalk.cxx
wxWakeUpIdle seems unnecessary here
[wxWidgets.git] / src / stc / scintilla / src / LexSmalltalk.cxx
1 // Scintilla source code edit control
2 /** @file LexSmalltalk.cxx
3 ** Lexer for Smalltalk language.
4 ** Written by Sergey Philippov, sphilippov-at-gmail-dot-com
5 **/
6 // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
7 // The License.txt file describes the conditions under which this software may be distributed.
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.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 | lexTable classificationBlock charClasses |
24 charClasses := #(#DecDigit #Letter #Special #Upper #BinSel).
25 lexTable := ByteArray new: 128.
26 classificationBlock := [ :charClass :chars |
27 | flag |
28 flag := 1 bitShift: (charClasses indexOf: charClass) - 1.
29 chars do: [ :char | lexTable at: char codePoint + 1 put: ((lexTable at: char codePoint + 1) bitOr: flag)]].
30
31 classificationBlock
32 value: #DecDigit value: '0123456789';
33 value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
34 value: #Special value: '()[]{};.^:';
35 value: #BinSel value: '~@%&*-+=|\/,<>?!';
36 value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
37
38 ((String new: 500) streamContents: [ :stream |
39 stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'.
40 lexTable keysAndValuesDo: [ :index :value |
41 ((index - 1) rem: 16) == 0 ifTrue: [
42 stream crLf; tab]
43 ifFalse: [
44 stream space].
45 stream print: value.
46 index ~= 256 ifTrue: [
47 stream nextPut: $,]].
48 stream crLf; nextPutAll: '};'; crLf.
49
50 charClasses keysAndValuesDo: [ :index :name |
51 stream
52 crLf;
53 nextPutAll: (
54 ('static inline bool is<1s>(int ch) {return (ch > 0) && (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}')
55 expandMacrosWith: name with: (1 bitShift: (index - 1)))
56 ]]) edit
57 */
58
59 // autogenerated {{{{
60
61 static int ClassificationTable[256] = {
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 16, 0, 0, 0, 16, 16, 0, 4, 4, 16, 16, 16, 16, 4, 16,
65 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 16, 16, 16, 16,
66 16, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
67 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 16, 4, 4, 2,
68 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
69 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 16, 4, 16, 0,
70 };
71
72 static inline bool isDecDigit(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 1) != 0);}
73 static inline bool isLetter(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 2) != 0);}
74 static inline bool isSpecial(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 4) != 0);}
75 static inline bool isUpper(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 8) != 0);}
76 static inline bool isBinSel(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 16) != 0);}
77 // autogenerated }}}}
78
79 static inline bool isAlphaNumeric(int ch) {
80 return isDecDigit(ch) || isLetter(ch);
81 }
82
83 static inline bool isDigitOfRadix(int ch, int radix)
84 {
85 if (isDecDigit(ch))
86 return (ch - '0') < radix;
87 else if (!isUpper(ch))
88 return false;
89 else
90 return (ch - 'A' + 10) < radix;
91 }
92
93 static inline void skipComment(StyleContext& sc)
94 {
95 while (sc.More() && sc.ch != '\"')
96 sc.Forward();
97 }
98
99 static inline void skipString(StyleContext& sc)
100 {
101 while (sc.More()) {
102 if (sc.ch == '\'') {
103 if (sc.chNext != '\'')
104 return;
105 sc.Forward();
106 }
107 sc.Forward();
108 }
109 }
110
111 static void handleHash(StyleContext& sc)
112 {
113 if (isSpecial(sc.chNext)) {
114 sc.SetState(SCE_ST_SPECIAL);
115 return;
116 }
117
118 sc.SetState(SCE_ST_SYMBOL);
119 sc.Forward();
120 if (sc.ch == '\'') {
121 sc.Forward();
122 skipString(sc);
123 }
124 else {
125 if (isLetter(sc.ch)) {
126 while (isAlphaNumeric(sc.chNext) || sc.chNext == ':')
127 sc.Forward();
128 }
129 else if (isBinSel(sc.ch)) {
130 while (isBinSel(sc.chNext))
131 sc.Forward();
132 }
133 }
134 }
135
136 static inline void handleSpecial(StyleContext& sc)
137 {
138 if (sc.ch == ':' && sc.chNext == '=') {
139 sc.SetState(SCE_ST_ASSIGN);
140 sc.Forward();
141 }
142 else {
143 if (sc.ch == '^')
144 sc.SetState(SCE_ST_RETURN);
145 else
146 sc.SetState(SCE_ST_SPECIAL);
147 }
148 }
149
150 static inline void skipInt(StyleContext& sc, int radix)
151 {
152 while (isDigitOfRadix(sc.chNext, radix))
153 sc.Forward();
154 }
155
156 static void handleNumeric(StyleContext& sc)
157 {
158 char num[256];
159 int nl;
160 int radix;
161
162 sc.SetState(SCE_ST_NUMBER);
163 num[0] = static_cast<char>(sc.ch);
164 nl = 1;
165 while (isDecDigit(sc.chNext)) {
166 num[nl++] = static_cast<char>(sc.chNext);
167 sc.Forward();
168 if (nl+1 == sizeof(num)/sizeof(num[0])) // overrun check
169 break;
170 }
171 if (sc.chNext == 'r') {
172 num[nl] = 0;
173 if (num[0] == '-')
174 radix = atoi(num + 1);
175 else
176 radix = atoi(num);
177 sc.Forward();
178 if (sc.chNext == '-')
179 sc.Forward();
180 skipInt(sc, radix);
181 }
182 else
183 radix = 10;
184 if (sc.chNext != '.' || !isDigitOfRadix(sc.GetRelative(2), radix))
185 return;
186 sc.Forward();
187 skipInt(sc, radix);
188 if (sc.chNext == 's') {
189 // ScaledDecimal
190 sc.Forward();
191 while (isDecDigit(sc.chNext))
192 sc.Forward();
193 return;
194 }
195 else if (sc.chNext != 'e' && sc.chNext != 'd' && sc.chNext != 'q')
196 return;
197 sc.Forward();
198 if (sc.chNext == '+' || sc.chNext == '-')
199 sc.Forward();
200 skipInt(sc, radix);
201 }
202
203 static inline void handleBinSel(StyleContext& sc)
204 {
205 sc.SetState(SCE_ST_BINARY);
206 while (isBinSel(sc.chNext))
207 sc.Forward();
208 }
209
210 static void handleLetter(StyleContext& sc, WordList* specialSelectorList)
211 {
212 char ident[256];
213 int il;
214 int state;
215 bool doubleColonPresent;
216
217 sc.SetState(SCE_ST_DEFAULT);
218
219 ident[0] = static_cast<char>(sc.ch);
220 il = 1;
221 while (isAlphaNumeric(sc.chNext)) {
222 ident[il++] = static_cast<char>(sc.chNext);
223 sc.Forward();
224 if (il+2 == sizeof(ident)/sizeof(ident[0])) // overrun check
225 break;
226 }
227
228 if (sc.chNext == ':') {
229 doubleColonPresent = true;
230 ident[il++] = ':';
231 sc.Forward();
232 }
233 else
234 doubleColonPresent = false;
235 ident[il] = 0;
236
237 if (specialSelectorList->InList(ident))
238 state = SCE_ST_SPEC_SEL;
239 else if (doubleColonPresent)
240 state = SCE_ST_KWSEND;
241 else if (isUpper(ident[0]))
242 state = SCE_ST_GLOBAL;
243 else {
244 if (!strcmp(ident, "self"))
245 state = SCE_ST_SELF;
246 else if (!strcmp(ident, "super"))
247 state = SCE_ST_SUPER;
248 else if (!strcmp(ident, "nil"))
249 state = SCE_ST_NIL;
250 else if (!strcmp(ident, "true") || !strcmp(ident, "false"))
251 state = SCE_ST_BOOL;
252 else
253 state = SCE_ST_DEFAULT;
254 }
255
256 sc.ChangeState(state);
257 }
258
259 static void colorizeSmalltalkDoc(unsigned int startPos, int length, int initStyle, WordList *wordLists[], Accessor &styler)
260 {
261 StyleContext sc(startPos, length, initStyle, styler);
262
263 if (initStyle == SCE_ST_COMMENT) {
264 skipComment(sc);
265 if (sc.More())
266 sc.Forward();
267 }
268 else if (initStyle == SCE_ST_STRING) {
269 skipString(sc);
270 if (sc.More())
271 sc.Forward();
272 }
273
274 for (; sc.More(); sc.Forward()) {
275 int ch;
276
277 ch = sc.ch;
278 if (ch == '\"') {
279 sc.SetState(SCE_ST_COMMENT);
280 sc.Forward();
281 skipComment(sc);
282 }
283 else if (ch == '\'') {
284 sc.SetState(SCE_ST_STRING);
285 sc.Forward();
286 skipString(sc);
287 }
288 else if (ch == '#')
289 handleHash(sc);
290 else if (ch == '$') {
291 sc.SetState(SCE_ST_CHARACTER);
292 sc.Forward();
293 }
294 else if (isSpecial(ch))
295 handleSpecial(sc);
296 else if (isDecDigit(ch))
297 handleNumeric(sc);
298 else if (isLetter(ch))
299 handleLetter(sc, wordLists[0]);
300 else if (isBinSel(ch)) {
301 if (ch == '-' && isDecDigit(sc.chNext))
302 handleNumeric(sc);
303 else
304 handleBinSel(sc);
305 }
306 else
307 sc.SetState(SCE_ST_DEFAULT);
308 }
309 sc.Complete();
310 }
311
312 static const char* const smalltalkWordListDesc[] = {
313 "Special selectors",
314 0
315 };
316
317 LexerModule lmSmalltalk(SCLEX_SMALLTALK, colorizeSmalltalkDoc, "smalltalk", NULL, smalltalkWordListDesc);