]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexLisp.cxx
e1d06cbac445c2483da5a075aee66f3539105d7c
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
== ')' || 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 (ch
== ':' && isLispwordstart(chNext
)) {
104 styler
.ColourTo(i
- 1, state
);
105 state
= SCE_LISP_SYMBOL
;
106 } else if (isLispwordstart(ch
)) {
107 styler
.ColourTo(i
- 1, state
);
108 state
= SCE_LISP_IDENTIFIER
;
110 else if (ch
== ';') {
111 styler
.ColourTo(i
- 1, state
);
112 state
= SCE_LISP_COMMENT
;
114 else if (isLispoperator(ch
) || ch
=='\'') {
115 styler
.ColourTo(i
- 1, state
);
116 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
117 if (ch
=='\'' && isLispwordstart(chNext
)) {
118 state
= SCE_LISP_SYMBOL
;
121 else if (ch
== '\"') {
122 styler
.ColourTo(i
- 1, state
);
123 state
= SCE_LISP_STRING
;
125 } else if (state
== SCE_LISP_IDENTIFIER
|| state
== SCE_LISP_SYMBOL
) {
126 if (!isLispwordstart(ch
)) {
127 if (state
== SCE_LISP_IDENTIFIER
) {
128 classifyWordLisp(styler
.GetStartSegment(), i
- 1, keywords
, keywords_kw
, styler
);
130 styler
.ColourTo(i
- 1, state
);
132 state
= SCE_LISP_DEFAULT
;
134 if (isLispoperator(ch
) || ch
=='\'') {
135 styler
.ColourTo(i
- 1, state
);
136 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
137 if (ch
=='\'' && isLispwordstart(chNext
)) {
138 state
= SCE_LISP_SYMBOL
;
141 } else if (state
== SCE_LISP_MACRO_DISPATCH
) {
143 if (ch
!= 'r' && ch
!= 'R' && (i
- styler
.GetStartSegment()) > 1) {
144 state
= SCE_LISP_DEFAULT
;
147 case '|': state
= SCE_LISP_MULTI_COMMENT
; break;
149 case 'O': radix
= 8; state
= SCE_LISP_MACRO
; break;
151 case 'X': radix
= 16; state
= SCE_LISP_MACRO
; break;
153 case 'B': radix
= 2; state
= SCE_LISP_MACRO
; break;
154 case '\\': state
= SCE_LISP_CHARACTER
; break;
157 case '+': state
= SCE_LISP_MACRO
; break;
158 case '\'': if (isLispwordstart(chNext
)) {
159 state
= SCE_LISP_SPECIAL
;
161 styler
.ColourTo(i
- 1, SCE_LISP_DEFAULT
);
162 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
163 state
= SCE_LISP_DEFAULT
;
166 default: if (isLispoperator(ch
)) {
167 styler
.ColourTo(i
- 1, SCE_LISP_DEFAULT
);
168 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
170 state
= SCE_LISP_DEFAULT
;
175 } else if (state
== SCE_LISP_MACRO
) {
176 if (isLispwordstart(ch
) && (radix
== -1 || IsADigit(ch
, radix
))) {
177 state
= SCE_LISP_SPECIAL
;
179 state
= SCE_LISP_DEFAULT
;
181 } else if (state
== SCE_LISP_CHARACTER
) {
182 if (isLispoperator(ch
)) {
183 styler
.ColourTo(i
, SCE_LISP_SPECIAL
);
184 state
= SCE_LISP_DEFAULT
;
185 } else if (isLispwordstart(ch
)) {
186 styler
.ColourTo(i
, SCE_LISP_SPECIAL
);
187 state
= SCE_LISP_SPECIAL
;
189 state
= SCE_LISP_DEFAULT
;
191 } else if (state
== SCE_LISP_SPECIAL
) {
192 if (!isLispwordstart(ch
) || (radix
!= -1 && !IsADigit(ch
, radix
))) {
193 styler
.ColourTo(i
- 1, state
);
194 state
= SCE_LISP_DEFAULT
;
196 if (isLispoperator(ch
) || ch
=='\'') {
197 styler
.ColourTo(i
- 1, state
);
198 styler
.ColourTo(i
, SCE_LISP_OPERATOR
);
199 if (ch
=='\'' && isLispwordstart(chNext
)) {
200 state
= SCE_LISP_SYMBOL
;
204 if (state
== SCE_LISP_COMMENT
) {
206 styler
.ColourTo(i
- 1, state
);
207 state
= SCE_LISP_DEFAULT
;
209 } else if (state
== SCE_LISP_MULTI_COMMENT
) {
210 if (ch
== '|' && chNext
== '#') {
212 chNext
= styler
.SafeGetCharAt(i
+ 1);
213 styler
.ColourTo(i
, state
);
214 state
= SCE_LISP_DEFAULT
;
216 } else if (state
== SCE_LISP_STRING
) {
218 if (chNext
== '\"' || chNext
== '\'' || chNext
== '\\') {
220 chNext
= styler
.SafeGetCharAt(i
+ 1);
222 } else if (ch
== '\"') {
223 styler
.ColourTo(i
, state
);
224 state
= SCE_LISP_DEFAULT
;
230 styler
.ColourTo(lengthDoc
- 1, state
);
233 static void FoldLispDoc(unsigned int startPos
, int length
, int /* initStyle */, WordList
*[],
235 unsigned int lengthDoc
= startPos
+ length
;
236 int visibleChars
= 0;
237 int lineCurrent
= styler
.GetLine(startPos
);
238 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
239 int levelCurrent
= levelPrev
;
240 char chNext
= styler
[startPos
];
241 int styleNext
= styler
.StyleAt(startPos
);
242 for (unsigned int i
= startPos
; i
< lengthDoc
; i
++) {
244 chNext
= styler
.SafeGetCharAt(i
+ 1);
245 int style
= styleNext
;
246 styleNext
= styler
.StyleAt(i
+ 1);
247 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
248 if (style
== SCE_LISP_OPERATOR
) {
249 if (ch
== '(' || ch
== '[' || ch
== '{') {
251 } else if (ch
== ')' || ch
== ']' || ch
== '}') {
257 if (visibleChars
== 0)
258 lev
|= SC_FOLDLEVELWHITEFLAG
;
259 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
260 lev
|= SC_FOLDLEVELHEADERFLAG
;
261 if (lev
!= styler
.LevelAt(lineCurrent
)) {
262 styler
.SetLevel(lineCurrent
, lev
);
265 levelPrev
= levelCurrent
;
268 if (!isspacechar(ch
))
271 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
272 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
273 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
276 static const char * const lispWordListDesc
[] = {
277 "Functions and special operators",
282 LexerModule
lmLISP(SCLEX_LISP
, ColouriseLispDoc
, "lisp", FoldLispDoc
, lispWordListDesc
);