]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/LexForth.cxx
1 // Scintilla source code edit control
2 /** @file LexCrontab.cxx
3 ** Lexer to use with extended crontab files used by a powerful
4 ** Windows scheduler/event monitor/automation manager nnCron.
5 ** (http://nemtsev.eserv.ru/)
7 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
8 // The License.txt file describes the conditions under which this software may be distributed.
21 #include "Scintilla.h"
24 bool is_whitespace(int ch
){
25 return ch
== '\n' || ch
== '\r' || ch
== '\t' || ch
== ' ';
28 bool is_blank(int ch
){
29 return ch
== '\t' || ch
== ' ';
34 #define log(x) fputs(f_debug,x);
43 static int cur_pos
,pos1
,pos2
,pos0
,lengthDoc
;
46 char getChar(bool is_bl
){
47 char ch
=st
->SafeGetCharAt(cur_pos
);
48 if(is_bl
) if(is_whitespace(ch
)) ch
=BL
;
53 char ch
=st
->SafeGetCharAt(cur_pos
);
57 return ch
=='\n' || ch
=='\r';
60 int parse(char ch
, bool skip_eol
){
61 // pos1 - start pos of word
62 // pos2 - pos after of word
67 pos0
=pos1
=pos2
=cur_pos
;
68 for(;cur_pos
<lengthDoc
&& (c
=getChar(is_bl
))==ch
; cur_pos
++){
69 if(is_eol(c
) && !skip_eol
){
76 if(cur_pos
==lengthDoc
) return 0;
77 for(len
=0;cur_pos
<lengthDoc
&& (c
=getChar(is_bl
))!=ch
; cur_pos
++){
78 if(is_eol(c
) && !skip_eol
) break;
85 fprintf(f_debug
,"parse: %c %s\n",ch
,buffer
);
90 bool _is_number(char *s
,int base
){
92 int digit
=((int)*s
)-(int)'0';
94 fprintf(f_debug
,"digit: %c %d\n",*s
,digit
);
96 if(digit
>9 && base
>10) digit
-=7;
97 if(digit
<0) return false;
98 if(digit
>=base
) return false;
103 bool is_number(char *s
){
104 if(strncmp(s
,"0x",2)==0) return _is_number(s
+2,16);
105 return _is_number(s
,10);
108 static void ColouriseForthDoc(unsigned int startPos
, int length
, int, WordList
*keywordLists
[], Accessor
&styler
)
112 lengthDoc
= startPos
+ length
;
113 buffer
= new char[length
];
116 f_debug
=fopen("c:\\sci.log","at");
119 WordList
&control
= *keywordLists
[0];
120 WordList
&keyword
= *keywordLists
[1];
121 WordList
&defword
= *keywordLists
[2];
122 WordList
&preword1
= *keywordLists
[3];
123 WordList
&preword2
= *keywordLists
[4];
124 WordList
&strings
= *keywordLists
[5];
126 // go through all provided text segment
127 // using the hand-written state machine shown below
128 styler
.StartAt(startPos
);
129 styler
.StartSegment(startPos
);
130 while(parse(BL
,true)!=0){
132 styler
.ColourTo(pos0
,SCE_FORTH_DEFAULT
);
133 styler
.ColourTo(pos1
-1,SCE_FORTH_DEFAULT
);
135 if(strcmp("\\",buffer
)==0){
136 styler
.ColourTo(pos1
,SCE_FORTH_COMMENT
);
138 styler
.ColourTo(pos2
,SCE_FORTH_COMMENT
);
139 }else if(strcmp("(",buffer
)==0){
140 styler
.ColourTo(pos1
,SCE_FORTH_COMMENT
);
142 if(cur_pos
<lengthDoc
) cur_pos
++;
143 styler
.ColourTo(cur_pos
,SCE_FORTH_COMMENT
);
144 }else if(strcmp("[",buffer
)==0){
145 styler
.ColourTo(pos1
,SCE_FORTH_STRING
);
147 if(cur_pos
<lengthDoc
) cur_pos
++;
148 styler
.ColourTo(cur_pos
,SCE_FORTH_STRING
);
149 }else if(strcmp("{",buffer
)==0){
150 styler
.ColourTo(pos1
,SCE_FORTH_LOCALE
);
152 if(cur_pos
<lengthDoc
) cur_pos
++;
153 styler
.ColourTo(cur_pos
,SCE_FORTH_LOCALE
);
154 }else if(strings
.InList(buffer
)) {
155 styler
.ColourTo(pos1
,SCE_FORTH_STRING
);
157 if(cur_pos
<lengthDoc
) cur_pos
++;
158 styler
.ColourTo(cur_pos
,SCE_FORTH_STRING
);
159 }else if(control
.InList(buffer
)) {
160 styler
.ColourTo(pos1
,SCE_FORTH_CONTROL
);
161 styler
.ColourTo(pos2
,SCE_FORTH_CONTROL
);
162 }else if(keyword
.InList(buffer
)) {
163 styler
.ColourTo(pos1
,SCE_FORTH_KEYWORD
);
164 styler
.ColourTo(pos2
,SCE_FORTH_KEYWORD
);
165 }else if(defword
.InList(buffer
)) {
166 styler
.ColourTo(pos1
,SCE_FORTH_KEYWORD
);
167 styler
.ColourTo(pos2
,SCE_FORTH_KEYWORD
);
169 styler
.ColourTo(pos1
-1,SCE_FORTH_DEFAULT
);
170 styler
.ColourTo(pos1
,SCE_FORTH_DEFWORD
);
171 styler
.ColourTo(pos2
,SCE_FORTH_DEFWORD
);
172 }else if(preword1
.InList(buffer
)) {
173 styler
.ColourTo(pos1
,SCE_FORTH_PREWORD1
);
175 styler
.ColourTo(pos2
,SCE_FORTH_PREWORD1
);
176 }else if(preword2
.InList(buffer
)) {
177 styler
.ColourTo(pos1
,SCE_FORTH_PREWORD2
);
179 styler
.ColourTo(pos2
,SCE_FORTH_PREWORD2
);
181 styler
.ColourTo(pos1
,SCE_FORTH_STRING
);
182 styler
.ColourTo(pos2
,SCE_FORTH_STRING
);
183 }else if(is_number(buffer
)){
184 styler
.ColourTo(pos1
,SCE_FORTH_NUMBER
);
185 styler
.ColourTo(pos2
,SCE_FORTH_NUMBER
);
194 if(control.InList(buffer)) {
195 styler.ColourTo(i,SCE_FORTH_CONTROL);
196 } else if(keyword.InList(buffer)) {
197 styler.ColourTo(i-1,SCE_FORTH_KEYWORD );
198 } else if(defword.InList(buffer)) {
199 styler.ColourTo(i-1,SCE_FORTH_DEFWORD );
200 // prev_state=SCE_FORTH_DEFWORD
201 } else if(preword1.InList(buffer)) {
202 styler.ColourTo(i-1,SCE_FORTH_PREWORD1 );
203 // state=SCE_FORTH_PREWORD1;
204 } else if(preword2.InList(buffer)) {
205 styler.ColourTo(i-1,SCE_FORTH_PREWORD2 );
207 styler.ColourTo(i-1,SCE_FORTH_DEFAULT);
212 for (int i = startPos; i < lengthDoc; i++) {
214 chNext = styler.SafeGetCharAt(i + 1);
215 if(i!=startPos) chPrev=styler.SafeGetCharAt(i - 1);
217 if (styler.IsLeadByte(ch)) {
218 chNext = styler.SafeGetCharAt(i + 2);
223 fprintf(f_debug,"%c %d ",ch,state);
226 case SCE_FORTH_DEFAULT:
227 if(is_whitespace(ch)) {
228 // whitespace is simply ignored here...
229 styler.ColourTo(i,SCE_FORTH_DEFAULT);
231 } else if( ch == '\\' && is_blank(chNext)) {
232 // signals the start of an one line comment...
233 state = SCE_FORTH_COMMENT;
234 styler.ColourTo(i,SCE_FORTH_COMMENT);
235 } else if( is_whitespace(chPrev) && ch == '(' && is_whitespace(chNext)) {
236 // signals the start of a plain comment...
237 state = SCE_FORTH_COMMENT_ML;
238 styler.ColourTo(i,SCE_FORTH_COMMENT_ML);
239 } else if( isdigit(ch) ) {
240 // signals the start of a number
242 buffer[bufferCount++] = ch;
243 state = SCE_FORTH_NUMBER;
244 } else if( !is_whitespace(ch)) {
245 // signals the start of an identifier
247 buffer[bufferCount++] = ch;
248 state = SCE_FORTH_IDENTIFIER;
250 // style it the default style..
251 styler.ColourTo(i,SCE_FORTH_DEFAULT);
255 case SCE_FORTH_COMMENT:
256 // if we find a newline here,
257 // we simply go to default state
258 // else continue to work on it...
259 if( ch == '\n' || ch == '\r' ) {
260 state = SCE_FORTH_DEFAULT;
262 styler.ColourTo(i,SCE_FORTH_COMMENT);
266 case SCE_FORTH_COMMENT_ML:
268 state = SCE_FORTH_DEFAULT;
270 styler.ColourTo(i+1,SCE_FORTH_COMMENT_ML);
274 case SCE_FORTH_IDENTIFIER:
275 // stay in CONF_IDENTIFIER state until we find a non-alphanumeric
276 if( !is_whitespace(ch) ) {
277 buffer[bufferCount++] = ch;
279 state = SCE_FORTH_DEFAULT;
280 buffer[bufferCount] = '\0';
282 fprintf(f_debug,"\nid %s\n",buffer);
285 // check if the buffer contains a keyword,
286 // and highlight it if it is a keyword...
287 // switch(prev_state)
288 // case SCE_FORTH_DEFAULT:
289 if(control.InList(buffer)) {
290 styler.ColourTo(i,SCE_FORTH_CONTROL);
291 } else if(keyword.InList(buffer)) {
292 styler.ColourTo(i-1,SCE_FORTH_KEYWORD );
293 } else if(defword.InList(buffer)) {
294 styler.ColourTo(i-1,SCE_FORTH_DEFWORD );
295 // prev_state=SCE_FORTH_DEFWORD
296 } else if(preword1.InList(buffer)) {
297 styler.ColourTo(i-1,SCE_FORTH_PREWORD1 );
298 // state=SCE_FORTH_PREWORD1;
299 } else if(preword2.InList(buffer)) {
300 styler.ColourTo(i-1,SCE_FORTH_PREWORD2 );
302 styler.ColourTo(i-1,SCE_FORTH_DEFAULT);
307 // push back the faulty character
308 chNext = styler[i--];
312 case SCE_FORTH_NUMBER:
313 // stay in CONF_NUMBER state until we find a non-numeric
315 buffer[bufferCount++] = ch;
317 state = SCE_FORTH_DEFAULT;
318 buffer[bufferCount] = '\0';
319 // Colourize here... (normal number)
320 styler.ColourTo(i-1,SCE_FORTH_NUMBER);
321 // push back a character
322 chNext = styler[i--];
334 static void FoldForthDoc(unsigned int, int, int, WordList
*[],
338 static const char * const forthWordLists
[] = {
342 "prewords with one argument",
343 "prewords with two arguments",
344 "string definition keywords",
348 LexerModule
lmForth(SCLEX_FORTH
, ColouriseForthDoc
, "forth",FoldForthDoc
,forthWordLists
);