OSDN Git Service

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