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