]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexLisp.cxx
WinCE doesn't have GetThreadLocale
[wxWidgets.git] / src / stc / scintilla / src / LexLisp.cxx
1 // Scintilla source code edit control
2 /** @file LexLisp.cxx
3 ** Lexer for Lisp.
4 ** Written by Alexey Yutkin.
5 **/
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.
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.h>
12 #include <stdio.h>
13 #include <stdarg.h>
14
15 #include "Platform.h"
16
17 #include "PropSet.h"
18 #include "Accessor.h"
19 #include "KeyWords.h"
20 #include "Scintilla.h"
21 #include "SciLexer.h"
22
23
24 static inline bool isLispoperator(char ch) {
25 if (isascii(ch) && isalnum(ch))
26 return false;
27 if (ch == '\'' || ch == '(' || ch == ')' )
28 return true;
29 return false;
30 }
31
32 static inline bool isLispwordstart(char ch) {
33 return isascii(ch) && ch != ';' && !isspacechar(ch) && !isLispoperator(ch) &&
34 ch != '\n' && ch != '\r' && ch != '\"';
35 }
36
37
38 static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
39 PLATFORM_ASSERT(end >= start);
40 char s[100];
41 unsigned int i;
42 bool digit_flag = true;
43 for (i = 0; (i < end - start + 1) && (i < 99); i++) {
44 s[i] = styler[start + i];
45 s[i + 1] = '\0';
46 if (!isdigit(s[i]) && (s[i] != '.')) digit_flag = false;
47 }
48 char chAttr = SCE_LISP_IDENTIFIER;
49
50 if(digit_flag) chAttr = SCE_LISP_NUMBER;
51 else {
52 if (keywords.InList(s)) {
53 chAttr = SCE_LISP_KEYWORD;
54 }
55 }
56 styler.ColourTo(end, chAttr);
57 return;
58 }
59
60
61 static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
62 Accessor &styler) {
63
64 WordList &keywords = *keywordlists[0];
65
66 styler.StartAt(startPos);
67
68 int state = initStyle;
69 char chNext = styler[startPos];
70 unsigned int lengthDoc = startPos + length;
71 styler.StartSegment(startPos);
72 for (unsigned int i = startPos; i < lengthDoc; i++) {
73 char ch = chNext;
74 chNext = styler.SafeGetCharAt(i + 1);
75
76 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
77
78 if (styler.IsLeadByte(ch)) {
79 chNext = styler.SafeGetCharAt(i + 2);
80 i += 1;
81 continue;
82 }
83
84 if (state == SCE_LISP_DEFAULT) {
85 if (isLispwordstart(ch)) {
86 styler.ColourTo(i - 1, state);
87 state = SCE_LISP_IDENTIFIER;
88 }
89 else if (ch == ';') {
90 styler.ColourTo(i - 1, state);
91 state = SCE_LISP_COMMENT;
92 }
93 else if (isLispoperator(ch) || ch=='\'') {
94 styler.ColourTo(i - 1, state);
95 styler.ColourTo(i, SCE_LISP_OPERATOR);
96 }
97 else if (ch == '\"') {
98 styler.ColourTo(i - 1, state);
99 state = SCE_LISP_STRING;
100 }
101 } else if (state == SCE_LISP_IDENTIFIER) {
102 if (!isLispwordstart(ch)) {
103 classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, styler);
104 state = SCE_LISP_DEFAULT;
105 } /*else*/
106 if (isLispoperator(ch) || ch=='\'') {
107 styler.ColourTo(i - 1, state);
108 styler.ColourTo(i, SCE_LISP_OPERATOR);
109 }
110
111 } else {
112 if (state == SCE_LISP_COMMENT) {
113 if (atEOL) {
114 styler.ColourTo(i - 1, state);
115 state = SCE_LISP_DEFAULT;
116 }
117 } else if (state == SCE_LISP_STRING) {
118 if (ch == '\\') {
119 if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
120 i++;
121 chNext = styler.SafeGetCharAt(i + 1);
122 }
123 } else if (ch == '\"') {
124 styler.ColourTo(i, state);
125 state = SCE_LISP_DEFAULT;
126 }
127 }
128 }
129
130 }
131 styler.ColourTo(lengthDoc - 1, state);
132 }
133
134 static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
135 Accessor &styler) {
136 unsigned int lengthDoc = startPos + length;
137 int visibleChars = 0;
138 int lineCurrent = styler.GetLine(startPos);
139 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
140 int levelCurrent = levelPrev;
141 char chNext = styler[startPos];
142 int styleNext = styler.StyleAt(startPos);
143 for (unsigned int i = startPos; i < lengthDoc; i++) {
144 char ch = chNext;
145 chNext = styler.SafeGetCharAt(i + 1);
146 int style = styleNext;
147 styleNext = styler.StyleAt(i + 1);
148 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
149 if (style == SCE_LISP_OPERATOR) {
150 if (ch == '(') {
151 levelCurrent++;
152 } else if (ch == ')') {
153 levelCurrent--;
154 }
155 }
156 if (atEOL) {
157 int lev = levelPrev;
158 if (visibleChars == 0)
159 lev |= SC_FOLDLEVELWHITEFLAG;
160 if ((levelCurrent > levelPrev) && (visibleChars > 0))
161 lev |= SC_FOLDLEVELHEADERFLAG;
162 if (lev != styler.LevelAt(lineCurrent)) {
163 styler.SetLevel(lineCurrent, lev);
164 }
165 lineCurrent++;
166 levelPrev = levelCurrent;
167 visibleChars = 0;
168 }
169 if (!isspacechar(ch))
170 visibleChars++;
171 }
172 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
173 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
174 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
175 }
176
177 static const char * const lispWordListDesc[] = {
178 "Keywords",
179 0
180 };
181
182 LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc, lispWordListDesc);