]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexGAP.cxx
1 // Scintilla source code edit control
3 ** Lexer for the GAP language. (The GAP System for Computational Discrete Algebra)
4 ** http://www.gap-system.org
6 // Copyright 2007 by Istvan Szollosi ( szteven <at> gmail <dot> com )
7 // The License.txt file describes the conditions under which this software may be distributed.
19 #include "StyleContext.h"
21 #include "Scintilla.h"
25 using namespace Scintilla
;
28 static inline bool IsGAPOperator(char ch
) {
29 if (isalnum(ch
)) return false;
30 if (ch
== '+' || ch
== '-' || ch
== '*' || ch
== '/' ||
31 ch
== '^' || ch
== ',' || ch
== '!' || ch
== '.' ||
32 ch
== '=' || ch
== '<' || ch
== '>' || ch
== '(' ||
33 ch
== ')' || ch
== ';' || ch
== '[' || ch
== ']' ||
34 ch
== '{' || ch
== '}' || ch
== ':' )
39 static void GetRange(unsigned int start
, unsigned int end
, Accessor
&styler
, char *s
, unsigned int len
) {
41 while ((i
< end
- start
+ 1) && (i
< len
-1)) {
42 s
[i
] = static_cast<char>(styler
[start
+ i
]);
48 static void ColouriseGAPDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[], Accessor
&styler
) {
50 WordList
&keywords1
= *keywordlists
[0];
51 WordList
&keywords2
= *keywordlists
[1];
52 WordList
&keywords3
= *keywordlists
[2];
53 WordList
&keywords4
= *keywordlists
[3];
55 // Do not leak onto next line
56 if (initStyle
== SCE_GAP_STRINGEOL
) initStyle
= SCE_GAP_DEFAULT
;
58 StyleContext
sc(startPos
, length
, initStyle
, styler
);
60 for (; sc
.More(); sc
.Forward()) {
62 // Prevent SCE_GAP_STRINGEOL from leaking back to previous line
63 if ( sc
.atLineStart
) {
64 if (sc
.state
== SCE_GAP_STRING
) sc
.SetState(SCE_GAP_STRING
);
65 if (sc
.state
== SCE_GAP_CHAR
) sc
.SetState(SCE_GAP_CHAR
);
68 // Handle line continuation generically
70 if (sc
.chNext
== '\n' || sc
.chNext
== '\r') {
72 if (sc
.ch
== '\r' && sc
.chNext
== '\n') {
79 // Determine if the current state should terminate
81 case SCE_GAP_OPERATOR
:
82 sc
.SetState(SCE_GAP_DEFAULT
);
86 if (!IsADigit(sc
.ch
)) {
89 if (!IsADigit(sc
.chNext
)) {
91 sc
.ChangeState(SCE_GAP_IDENTIFIER
);
94 } else if (isalpha(sc
.ch
) || sc
.ch
== '_') {
95 sc
.ChangeState(SCE_GAP_IDENTIFIER
);
97 else sc
.SetState(SCE_GAP_DEFAULT
);
101 case SCE_GAP_IDENTIFIER
:
102 if (!(iswordstart(static_cast<char>(sc
.ch
)) || sc
.ch
== '$')) {
103 if (sc
.ch
== '\\') sc
.Forward();
106 sc
.GetCurrent(s
, sizeof(s
));
107 if (keywords1
.InList(s
)) {
108 sc
.ChangeState(SCE_GAP_KEYWORD
);
109 } else if (keywords2
.InList(s
)) {
110 sc
.ChangeState(SCE_GAP_KEYWORD2
);
111 } else if (keywords3
.InList(s
)) {
112 sc
.ChangeState(SCE_GAP_KEYWORD3
);
113 } else if (keywords4
.InList(s
)) {
114 sc
.ChangeState(SCE_GAP_KEYWORD4
);
116 sc
.SetState(SCE_GAP_DEFAULT
);
121 case SCE_GAP_COMMENT
:
123 sc
.SetState(SCE_GAP_DEFAULT
);
129 sc
.ChangeState(SCE_GAP_STRINGEOL
);
130 } else if (sc
.ch
== '\\') {
131 if (sc
.chNext
== '\"' || sc
.chNext
== '\'' || sc
.chNext
== '\\') {
134 } else if (sc
.ch
== '\"') {
135 sc
.ForwardSetState(SCE_GAP_DEFAULT
);
141 sc
.ChangeState(SCE_GAP_STRINGEOL
);
142 } else if (sc
.ch
== '\\') {
143 if (sc
.chNext
== '\"' || sc
.chNext
== '\'' || sc
.chNext
== '\\') {
146 } else if (sc
.ch
== '\'') {
147 sc
.ForwardSetState(SCE_GAP_DEFAULT
);
151 case SCE_GAP_STRINGEOL
:
152 if (sc
.atLineStart
) {
153 sc
.SetState(SCE_GAP_DEFAULT
);
158 // Determine if a new state should be entered
159 if (sc
.state
== SCE_GAP_DEFAULT
) {
160 if (IsGAPOperator(static_cast<char>(sc
.ch
))) {
161 sc
.SetState(SCE_GAP_OPERATOR
);
163 else if (IsADigit(sc
.ch
)) {
164 sc
.SetState(SCE_GAP_NUMBER
);
165 } else if (isalpha(sc
.ch
) || sc
.ch
== '_' || sc
.ch
== '\\' || sc
.ch
== '$' || sc
.ch
== '~') {
166 sc
.SetState(SCE_GAP_IDENTIFIER
);
167 if (sc
.ch
== '\\') sc
.Forward();
168 } else if (sc
.ch
== '#') {
169 sc
.SetState(SCE_GAP_COMMENT
);
170 } else if (sc
.ch
== '\"') {
171 sc
.SetState(SCE_GAP_STRING
);
172 } else if (sc
.ch
== '\'') {
173 sc
.SetState(SCE_GAP_CHAR
);
181 static int ClassifyFoldPointGAP(const char* s
) {
183 if (strcmp(s
, "function") == 0 ||
184 strcmp(s
, "do") == 0 ||
185 strcmp(s
, "if") == 0 ||
186 strcmp(s
, "repeat") == 0 ) {
188 } else if (strcmp(s
, "end") == 0 ||
189 strcmp(s
, "od") == 0 ||
190 strcmp(s
, "fi") == 0 ||
191 strcmp(s
, "until") == 0 ) {
197 static void FoldGAPDoc( unsigned int startPos
, int length
, int initStyle
, WordList
** , Accessor
&styler
) {
198 unsigned int endPos
= startPos
+ length
;
199 int visibleChars
= 0;
200 int lineCurrent
= styler
.GetLine(startPos
);
201 int levelPrev
= styler
.LevelAt(lineCurrent
) & SC_FOLDLEVELNUMBERMASK
;
202 int levelCurrent
= levelPrev
;
203 char chNext
= styler
[startPos
];
204 int styleNext
= styler
.StyleAt(startPos
);
205 int style
= initStyle
;
209 for (unsigned int i
= startPos
; i
< endPos
; i
++) {
211 chNext
= styler
.SafeGetCharAt(i
+ 1);
212 int stylePrev
= style
;
214 styleNext
= styler
.StyleAt(i
+ 1);
215 bool atEOL
= (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
217 if (stylePrev
!= SCE_GAP_KEYWORD
&& style
== SCE_GAP_KEYWORD
) {
218 // Store last word start point.
222 if (stylePrev
== SCE_GAP_KEYWORD
) {
223 if(iswordchar(ch
) && !iswordchar(chNext
)) {
225 GetRange(lastStart
, i
, styler
, s
, sizeof(s
));
226 levelCurrent
+= ClassifyFoldPointGAP(s
);
232 if ((levelCurrent
> levelPrev
) && (visibleChars
> 0))
233 lev
|= SC_FOLDLEVELHEADERFLAG
;
234 if (lev
!= styler
.LevelAt(lineCurrent
)) {
235 styler
.SetLevel(lineCurrent
, lev
);
238 levelPrev
= levelCurrent
;
242 if (!isspacechar(ch
))
246 int flagsNext
= styler
.LevelAt(lineCurrent
) & ~SC_FOLDLEVELNUMBERMASK
;
247 styler
.SetLevel(lineCurrent
, levelPrev
| flagsNext
);
250 static const char * const GAPWordListDesc
[] = {
253 "Keywords 3 (unused)",
254 "Keywords 4 (unused)",