]> git.saurik.com Git - wxWidgets.git/blame - src/stc/scintilla/lexers/LexSmalltalk.cxx
Added ability to switch off more components of the size page UI
[wxWidgets.git] / src / stc / scintilla / lexers / LexSmalltalk.cxx
CommitLineData
1e9bafca
RD
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>
1dcf666d
RD
11#include <stdio.h>
12#include <stdarg.h>
13#include <assert.h>
1e9bafca
RD
14#include <ctype.h>
15
1dcf666d
RD
16#include "ILexer.h"
17#include "Scintilla.h"
18#include "SciLexer.h"
1e9bafca 19
1dcf666d
RD
20#include "WordList.h"
21#include "LexAccessor.h"
1e9bafca
RD
22#include "Accessor.h"
23#include "StyleContext.h"
1dcf666d
RD
24#include "CharacterSet.h"
25#include "LexerModule.h"
1e9bafca 26
7e0c58e9
RD
27#ifdef SCI_NAMESPACE
28using namespace Scintilla;
29#endif
30
1e9bafca
RD
31/*
32| lexTable classificationBlock charClasses |
33charClasses := #(#DecDigit #Letter #Special #Upper #BinSel).
34lexTable := ByteArray new: 128.
35classificationBlock := [ :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
40classificationBlock
41 value: #DecDigit value: '0123456789';
42 value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
43 value: #Special value: '()[]{};.^:';
44 value: #BinSel value: '~@%&*-+=|\/,<>?!';
45 value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
46
1dcf666d 47((String new: 500) streamContents: [ :stream |
1e9bafca
RD
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.
1dcf666d 58
1e9bafca
RD
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
70static 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
81static inline bool isDecDigit(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 1) != 0);}
82static inline bool isLetter(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 2) != 0);}
83static inline bool isSpecial(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 4) != 0);}
84static inline bool isUpper(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 8) != 0);}
85static inline bool isBinSel(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 16) != 0);}
86// autogenerated }}}}
87
88static inline bool isAlphaNumeric(int ch) {
89 return isDecDigit(ch) || isLetter(ch);
90}
91
92static 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
102static inline void skipComment(StyleContext& sc)
1dcf666d 103{
1e9bafca
RD
104 while (sc.More() && sc.ch != '\"')
105 sc.Forward();
106}
107
108static 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
120static void handleHash(StyleContext& sc)
121{
122 if (isSpecial(sc.chNext)) {
123 sc.SetState(SCE_ST_SPECIAL);
124 return;
125 }
1dcf666d 126
1e9bafca
RD
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
145static 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
159static inline void skipInt(StyleContext& sc, int radix)
160{
161 while (isDigitOfRadix(sc.chNext, radix))
162 sc.Forward();
163}
164
165static void handleNumeric(StyleContext& sc)
166{
167 char num[256];
168 int nl;
169 int radix;
1dcf666d 170
1e9bafca
RD
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
212static inline void handleBinSel(StyleContext& sc)
213{
214 sc.SetState(SCE_ST_BINARY);
215 while (isBinSel(sc.chNext))
216 sc.Forward();
217}
218
219static void handleLetter(StyleContext& sc, WordList* specialSelectorList)
220{
221 char ident[256];
222 int il;
223 int state;
224 bool doubleColonPresent;
1dcf666d 225
1e9bafca
RD
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;
1dcf666d 245
1e9bafca
RD
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 }
1dcf666d 264
1e9bafca
RD
265 sc.ChangeState(state);
266}
267
268static 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;
1dcf666d 285
1e9bafca
RD
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
321static const char* const smalltalkWordListDesc[] = {
322 "Special selectors",
323 0
324};
325
326LexerModule lmSmalltalk(SCLEX_SMALLTALK, colorizeSmalltalkDoc, "smalltalk", NULL, smalltalkWordListDesc);