]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/lexers/LexLisp.cxx
1 // Scintilla source code edit control
4 ** Written by Alexey Yutkin.
6 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
7 // The License.txt file describes the conditions under which this software may be distributed.
17 #include "Scintilla.h"
21 #include "LexAccessor.h"
23 #include "StyleContext.h"
24 #include "CharacterSet.h"
25 #include "LexerModule.h"
28 using namespace Scintilla
;
31 #define SCE_LISP_CHARACTER 29
32 #define SCE_LISP_MACRO 30
33 #define SCE_LISP_MACRO_DISPATCH 31
35 static inline bool isLispoperator(char ch
) {
36 if (isascii(ch
) && isalnum(ch
))
38 if (ch
== '\'' || ch
== '`' || ch
== '(' || ch
== ')' || ch
== '[' || ch
== ']' || ch
== '{' || ch
== '}')
43 static inline bool isLispwordstart(char ch
) {
44 return isascii(ch
) && ch
!= ';' && !isspacechar(ch
) && !isLispoperator(ch
) &&
45 ch
!= '\n' && ch
!= '\r' && ch
!= '\"';
49 static void classifyWordLisp(unsigned int start
, unsigned int end
, WordList
&keywords
, WordList
&keywords_kw
, Accessor
&styler
) {
53 bool digit_flag
= true;
54 for (i
= 0; (i
< end
- start
+ 1) && (i
< 99); i
++) {
55 s
[i
] = styler
[start
+ i
];
57 if (!isdigit(s
[i
]) && (s
[i
] != '.')) digit_flag
= false;
59 char chAttr
= SCE_LISP_IDENTIFIER
;
61 if(digit_flag
) chAttr
= SCE_LISP_NUMBER
;
63 if (keywords
.InList(s
)) {
64 chAttr
= SCE_LISP_KEYWORD
;
65 } else if (keywords_kw
.InList(s
)) {
66 chAttr
= SCE_LISP_KEYWORD_KW
;
67 } else if ((s
[0] == '*' && s
[i
-1] == '*') ||
68 (s
[0] == '+' && s
[i
-1] == '+')) {
69 chAttr
= SCE_LISP_SPECIAL
;
72 styler
.ColourTo(end
, chAttr
);
77 static void ColouriseLispDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
80 WordList
&keywords
= *keywordlists
[0];
81 WordList
&keywords_kw
= *keywordlists
[1];
83 styler
.StartAt(startPos
);
85 int state
= initStyle
, radix
= -1;
86 char chNext
= styler
[startPos
];
87 unsigned int lengthDoc
= startPos
+ length
;
88 styler
.StartSegment(startPos
);
89 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
91 chNext
= styler
.SafeGetCharAt(i
+ 1);
93 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
95 if (styler
.IsLeadByte(ch
)) {
96 chNext
= styler
.SafeGetCharAt(i
+ 2);
101 if (state
== SCE_LISP_DEFAULT
) {
103 styler
.ColourTo(i
- 1, state
);
105 state
= SCE_LISP_MACRO_DISPATCH
;
106 } else if (ch
== ':' && isLispwordstart(chNext
)) {
107 styler
.ColourTo(i
- 1, state
);
108 state
= SCE_LISP_SYMBOL
;
109 } else if (isLispwordstart(ch
)) {
110 styler
.ColourTo(i
- 1, state
);
111 state
= SCE_LISP_IDENTIFIER
;
113 else if (ch
== ';') {
114 styler
.ColourTo(i
- 1, state
);
115 state
= SCE_LISP_COMMENT
;
117 else if (isLispoperator(ch
) || ch
=='\'') {
118 styler
.ColourTo(i
- 1, state
);
119 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
120 if (ch
=='\'' && isLispwordstart(chNext
)) {
121 state
= SCE_LISP_SYMBOL
;
124 else if (ch
== '\"') {
125 styler
.ColourTo(i
- 1, state
);
126 state
= SCE_LISP_STRING
;
128 } else if (state
== SCE_LISP_IDENTIFIER
|| state
== SCE_LISP_SYMBOL
) {
129 if (!isLispwordstart(ch
)) {
130 if (state
== SCE_LISP_IDENTIFIER
) {
131 classifyWordLisp(styler
.GetStartSegment(), i
- 1, keywords
, keywords_kw
, styler
);
133 styler
.ColourTo(i
- 1, state
);
135 state
= SCE_LISP_DEFAULT
;
137 if (isLispoperator(ch
) || ch
=='\'') {
138 styler
.ColourTo(i
- 1, state
);
139 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
140 if (ch
=='\'' && isLispwordstart(chNext
)) {
141 state
= SCE_LISP_SYMBOL
;
144 } else if (state
== SCE_LISP_MACRO_DISPATCH
) {
145 if (!(isascii(ch
) && isdigit(ch
))) {
146 if (ch
!= 'r' && ch
!= 'R' && (i
- styler
.GetStartSegment()) > 1) {
147 state
= SCE_LISP_DEFAULT
;
150 case '|': state
= SCE_LISP_MULTI_COMMENT
; break;
152 case 'O': radix
= 8; state
= SCE_LISP_MACRO
; break;
154 case 'X': radix
= 16; state
= SCE_LISP_MACRO
; break;
156 case 'B': radix
= 2; state
= SCE_LISP_MACRO
; break;
157 case '\\': state
= SCE_LISP_CHARACTER
; break;
160 case '+': state
= SCE_LISP_MACRO
; break;
161 case '\'': if (isLispwordstart(chNext
)) {
162 state
= SCE_LISP_SPECIAL
;
164 styler
.ColourTo(i
- 1, SCE_LISP_DEFAULT
);
165 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
166 state
= SCE_LISP_DEFAULT
;
169 default: if (isLispoperator(ch
)) {
170 styler
.ColourTo(i
- 1, SCE_LISP_DEFAULT
);
171 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
173 state
= SCE_LISP_DEFAULT
;
178 } else if (state
== SCE_LISP_MACRO
) {
179 if (isLispwordstart(ch
) && (radix
== -1 || IsADigit(ch
, radix
))) {
180 state
= SCE_LISP_SPECIAL
;
182 state
= SCE_LISP_DEFAULT
;
184 } else if (state
== SCE_LISP_CHARACTER
) {
185 if (isLispoperator(ch
)) {
186 styler
.ColourTo(i
, SCE_LISP_SPECIAL
);
187 state
= SCE_LISP_DEFAULT
;
188 } else if (isLispwordstart(ch
)) {
189 styler
.ColourTo(i
, SCE_LISP_SPECIAL
);
190 state
= SCE_LISP_SPECIAL
;
192 state
= SCE_LISP_DEFAULT
;
194 } else if (state
== SCE_LISP_SPECIAL
) {
195 if (!isLispwordstart(ch
) || (radix
!= -1 && !IsADigit(ch
, radix
))) {
196 styler
.ColourTo(i
- 1, state
);
197 state
= SCE_LISP_DEFAULT
;
199 if (isLispoperator(ch
) || ch
=='\'') {
200 styler
.ColourTo(i
- 1, state
);
201 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
202 if (ch
=='\'' && isLispwordstart(chNext
)) {
203 state
= SCE_LISP_SYMBOL
;
207 if (state
== SCE_LISP_COMMENT
) {
209 styler
.ColourTo(i
- 1, state
);
210 state
= SCE_LISP_DEFAULT
;
212 } else if (state
== SCE_LISP_MULTI_COMMENT
) {
213 if (ch
== '|' && chNext
== '#') {
215 chNext
= styler
.SafeGetCharAt(i
+ 1);
216 styler
.ColourTo(i
, state
);
217 state
= SCE_LISP_DEFAULT
;
219 } else if (state
== SCE_LISP_STRING
) {
221 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
223 chNext
= styler
.SafeGetCharAt(i
+ 1);
225 } else if (ch
== '\"') {
226 styler
.ColourTo(i
, state
);
227 state
= SCE_LISP_DEFAULT
;
233 styler
.ColourTo(lengthDoc
- 1, state
);
236 static void FoldLispDoc(unsigned int startPos
, int length
, int /* initStyle */, WordList
*[],
238 unsigned int lengthDoc
= startPos
+ length
;
239 int visibleChars
= 0;
240 int lineCurrent
= styler
.GetLine(startPos
);
241 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
242 int levelCurrent
= levelPrev
;
243 char chNext
= styler
[startPos
];
244 int styleNext
= styler
.StyleAt(startPos
);
245 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
247 chNext
= styler
.SafeGetCharAt(i
+ 1);
248 int style
= styleNext
;
249 styleNext
= styler
.StyleAt(i
+ 1);
250 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
251 if (style
== SCE_LISP_OPERATOR
) {
252 if (ch
== '(' || ch
== '[' || ch
== '{') {
254 } else if (ch
== ')' || ch
== ']' || ch
== '}') {
260 if (visibleChars
== 0)
261 lev
|= SC_FOLDLEVELWHITEFLAG
;
262 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
263 lev
|= SC_FOLDLEVELHEADERFLAG
;
264 if (lev
!= styler
.LevelAt(lineCurrent
)) {
265 styler
.SetLevel(lineCurrent
, lev
);
268 levelPrev
= levelCurrent
;
271 if (!isspacechar(ch
))
274 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
275 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
276 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
279 static const char * const lispWordListDesc
[] = {
280 "Functions and special operators",
285 LexerModule
lmLISP(SCLEX_LISP
, ColouriseLispDoc
, "lisp", FoldLispDoc
, lispWordListDesc
);