]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexLisp.cxx
1072e13a3af2fdd62274b7dc4a450df660128e4b
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.
20 #include "Scintilla.h"
22 #include "StyleContext.h"
25 using namespace Scintilla
;
28 #define SCE_LISP_CHARACTER 29
29 #define SCE_LISP_MACRO 30
30 #define SCE_LISP_MACRO_DISPATCH 31
32 static inline bool isLispoperator(char ch
) {
33 if (isascii(ch
) && isalnum(ch
))
35 if (ch
== '\'' || ch
== '`' || ch
== '(' || ch
== ')' )
40 static inline bool isLispwordstart(char ch
) {
41 return isascii(ch
) && ch
!= ';' && !isspacechar(ch
) && !isLispoperator(ch
) &&
42 ch
!= '\n' && ch
!= '\r' && ch
!= '\"';
46 static void classifyWordLisp(unsigned int start
, unsigned int end
, WordList
&keywords
, WordList
&keywords_kw
, Accessor
&styler
) {
47 PLATFORM_ASSERT(end
>= start
);
50 bool digit_flag
= true;
51 for (i
= 0; (i
< end
- start
+ 1) && (i
< 99); i
++) {
52 s
[i
] = styler
[start
+ i
];
54 if (!isdigit(s
[i
]) && (s
[i
] != '.')) digit_flag
= false;
56 char chAttr
= SCE_LISP_IDENTIFIER
;
58 if(digit_flag
) chAttr
= SCE_LISP_NUMBER
;
60 if (keywords
.InList(s
)) {
61 chAttr
= SCE_LISP_KEYWORD
;
62 } else if (keywords_kw
.InList(s
)) {
63 chAttr
= SCE_LISP_KEYWORD_KW
;
64 } else if ((s
[0] == '*' && s
[i
-1] == '*') ||
65 (s
[0] == '+' && s
[i
-1] == '+')) {
66 chAttr
= SCE_LISP_SPECIAL
;
69 styler
.ColourTo(end
, chAttr
);
74 static void ColouriseLispDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
77 WordList
&keywords
= *keywordlists
[0];
78 WordList
&keywords_kw
= *keywordlists
[1];
80 styler
.StartAt(startPos
);
82 int state
= initStyle
, radix
= -1;
83 char chNext
= styler
[startPos
];
84 unsigned int lengthDoc
= startPos
+ length
;
85 styler
.StartSegment(startPos
);
86 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
88 chNext
= styler
.SafeGetCharAt(i
+ 1);
90 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
92 if (styler
.IsLeadByte(ch
)) {
93 chNext
= styler
.SafeGetCharAt(i
+ 2);
98 if (state
== SCE_LISP_DEFAULT
) {
100 styler
.ColourTo(i
- 1, state
);
102 state
= SCE_LISP_MACRO_DISPATCH
;
103 } else if (isLispwordstart(ch
)) {
104 styler
.ColourTo(i
- 1, state
);
105 state
= SCE_LISP_IDENTIFIER
;
107 else if (ch
== ';') {
108 styler
.ColourTo(i
- 1, state
);
109 state
= SCE_LISP_COMMENT
;
111 else if (isLispoperator(ch
) || ch
=='\'') {
112 styler
.ColourTo(i
- 1, state
);
113 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
114 if (ch
=='\'' && isLispwordstart(chNext
)) {
115 state
= SCE_LISP_SYMBOL
;
118 else if (ch
== '\"') {
119 styler
.ColourTo(i
- 1, state
);
120 state
= SCE_LISP_STRING
;
122 } else if (state
== SCE_LISP_IDENTIFIER
|| state
== SCE_LISP_SYMBOL
) {
123 if (!isLispwordstart(ch
)) {
124 if (state
== SCE_LISP_IDENTIFIER
) {
125 classifyWordLisp(styler
.GetStartSegment(), i
- 1, keywords
, keywords_kw
, styler
);
127 styler
.ColourTo(i
- 1, state
);
129 state
= SCE_LISP_DEFAULT
;
131 if (isLispoperator(ch
) || ch
=='\'') {
132 styler
.ColourTo(i
- 1, state
);
133 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
134 if (ch
=='\'' && isLispwordstart(chNext
)) {
135 state
= SCE_LISP_SYMBOL
;
138 } else if (state
== SCE_LISP_MACRO_DISPATCH
) {
140 if (ch
!= 'r' && ch
!= 'R' && (i
- styler
.GetStartSegment()) > 1) {
141 state
= SCE_LISP_DEFAULT
;
144 case '|': state
= SCE_LISP_MULTI_COMMENT
; break;
146 case 'O': radix
= 8; state
= SCE_LISP_MACRO
; break;
148 case 'X': radix
= 16; state
= SCE_LISP_MACRO
; break;
150 case 'B': radix
= 2; state
= SCE_LISP_MACRO
; break;
151 case '\\': state
= SCE_LISP_CHARACTER
; break;
154 case '+': state
= SCE_LISP_MACRO
; break;
155 case '\'': if (isLispwordstart(chNext
)) {
156 state
= SCE_LISP_SPECIAL
;
158 styler
.ColourTo(i
- 1, SCE_LISP_DEFAULT
);
159 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
160 state
= SCE_LISP_DEFAULT
;
163 default: if (isLispoperator(ch
)) {
164 styler
.ColourTo(i
- 1, SCE_LISP_DEFAULT
);
165 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
167 state
= SCE_LISP_DEFAULT
;
172 } else if (state
== SCE_LISP_MACRO
) {
173 if (isLispwordstart(ch
) && (radix
== -1 || IsADigit(ch
, radix
))) {
174 state
= SCE_LISP_SPECIAL
;
176 state
= SCE_LISP_DEFAULT
;
178 } else if (state
== SCE_LISP_CHARACTER
) {
179 if (isLispoperator(ch
)) {
180 styler
.ColourTo(i
, SCE_LISP_SPECIAL
);
181 state
= SCE_LISP_DEFAULT
;
182 } else if (isLispwordstart(ch
)) {
183 styler
.ColourTo(i
, SCE_LISP_SPECIAL
);
184 state
= SCE_LISP_SPECIAL
;
186 state
= SCE_LISP_DEFAULT
;
188 } else if (state
== SCE_LISP_SPECIAL
) {
189 if (!isLispwordstart(ch
) || (radix
!= -1 && !IsADigit(ch
, radix
))) {
190 styler
.ColourTo(i
- 1, state
);
191 state
= SCE_LISP_DEFAULT
;
193 if (isLispoperator(ch
) || ch
=='\'') {
194 styler
.ColourTo(i
- 1, state
);
195 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
196 if (ch
=='\'' && isLispwordstart(chNext
)) {
197 state
= SCE_LISP_SYMBOL
;
201 if (state
== SCE_LISP_COMMENT
) {
203 styler
.ColourTo(i
- 1, state
);
204 state
= SCE_LISP_DEFAULT
;
206 } else if (state
== SCE_LISP_MULTI_COMMENT
) {
207 if (ch
== '|' && chNext
== '#') {
209 chNext
= styler
.SafeGetCharAt(i
+ 1);
210 styler
.ColourTo(i
, state
);
211 state
= SCE_LISP_DEFAULT
;
213 } else if (state
== SCE_LISP_STRING
) {
215 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
217 chNext
= styler
.SafeGetCharAt(i
+ 1);
219 } else if (ch
== '\"') {
220 styler
.ColourTo(i
, state
);
221 state
= SCE_LISP_DEFAULT
;
227 styler
.ColourTo(lengthDoc
- 1, state
);
230 static void FoldLispDoc(unsigned int startPos
, int length
, int /* initStyle */, WordList
*[],
232 unsigned int lengthDoc
= startPos
+ length
;
233 int visibleChars
= 0;
234 int lineCurrent
= styler
.GetLine(startPos
);
235 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
236 int levelCurrent
= levelPrev
;
237 char chNext
= styler
[startPos
];
238 int styleNext
= styler
.StyleAt(startPos
);
239 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
241 chNext
= styler
.SafeGetCharAt(i
+ 1);
242 int style
= styleNext
;
243 styleNext
= styler
.StyleAt(i
+ 1);
244 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
245 if (style
== SCE_LISP_OPERATOR
) {
248 } else if (ch
== ')') {
254 if (visibleChars
== 0)
255 lev
|= SC_FOLDLEVELWHITEFLAG
;
256 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
257 lev
|= SC_FOLDLEVELHEADERFLAG
;
258 if (lev
!= styler
.LevelAt(lineCurrent
)) {
259 styler
.SetLevel(lineCurrent
, lev
);
262 levelPrev
= levelCurrent
;
265 if (!isspacechar(ch
))
268 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
269 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
270 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
273 static const char * const lispWordListDesc
[] = {
274 "Functions and special operators",
279 LexerModule
lmLISP(SCLEX_LISP
, ColouriseLispDoc
, "lisp", FoldLispDoc
, lispWordListDesc
);