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