]> git.saurik.com Git - wxWidgets.git/blame - src/stc/scintilla/src/LexForth.cxx
wxFormatConverter test rewritten for CppUnit (patch #910051)
[wxWidgets.git] / src / stc / scintilla / src / LexForth.cxx
CommitLineData
8e54aaed
RD
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/)
6 **/
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.
9
10#include <stdlib.h>
11#include <string.h>
12#include <ctype.h>
13#include <stdio.h>
14#include <stdarg.h>
15
16#include "Platform.h"
17
18#include "PropSet.h"
19#include "Accessor.h"
20#include "KeyWords.h"
21#include "Scintilla.h"
22#include "SciLexer.h"
23
24bool is_whitespace(int ch){
25 return ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ';
26}
27
28bool is_blank(int ch){
29 return ch == '\t' || ch == ' ';
30}
31//#define FORTH_DEBUG
32#ifdef FORTH_DEBUG
33static FILE *f_debug;
34#define log(x) fputs(f_debug,x);
35#else
36#define log(x)
37#endif
38
39#define STATE_LOCALE
40#define BL ' '
41
42static Accessor *st;
43static int cur_pos,pos1,pos2,pos0,lengthDoc;
44char *buffer;
45
46char getChar(bool is_bl){
47 char ch=st->SafeGetCharAt(cur_pos);
48 if(is_bl) if(is_whitespace(ch)) ch=BL;
49 return ch;
50}
51
52char getCharBL(){
53 char ch=st->SafeGetCharAt(cur_pos);
54 return ch;
55}
56bool is_eol(char ch){
57 return ch=='\n' || ch=='\r';
58}
59
60int parse(char ch, bool skip_eol){
61// pos1 - start pos of word
62// pos2 - pos after of word
63// pos0 - start pos
64 char c=0;
65 int len;
66 bool is_bl=ch==BL;
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){
70 pos2=pos1;
71 return 0;
72 }
73 }
74 pos1=cur_pos;
75 pos2=pos1;
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;
79 pos2++;
80 buffer[len++]=c;
81 }
82 if(c==ch) pos2--;
83 buffer[len]='\0';
84#ifdef FORTH_DEBUG
85 fprintf(f_debug,"parse: %c %s\n",ch,buffer);
86#endif
87 return len;
88}
89
90bool _is_number(char *s,int base){
91 for(;*s;s++){
92 int digit=((int)*s)-(int)'0';
93#ifdef FORTH_DEBUG
94 fprintf(f_debug,"digit: %c %d\n",*s,digit);
95#endif
96 if(digit>9 && base>10) digit-=7;
97 if(digit<0) return false;
98 if(digit>=base) return false;
99 }
100 return true;
101}
102
103bool is_number(char *s){
104 if(strncmp(s,"0x",2)==0) return _is_number(s+2,16);
105 return _is_number(s,10);
106}
107
108static void ColouriseForthDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
109{
110 st=&styler;
111 cur_pos=startPos;
112 lengthDoc = startPos + length;
113 buffer = new char[length];
114
115#ifdef FORTH_DEBUG
116 f_debug=fopen("c:\\sci.log","at");
117#endif
118
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];
125
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){
131 if(pos0!=pos1){
132 styler.ColourTo(pos0,SCE_FORTH_DEFAULT);
133 styler.ColourTo(pos1-1,SCE_FORTH_DEFAULT);
134 }
135 if(strcmp("\\",buffer)==0){
136 styler.ColourTo(pos1,SCE_FORTH_COMMENT);
137 parse(1,false);
138 styler.ColourTo(pos2,SCE_FORTH_COMMENT);
139 }else if(strcmp("(",buffer)==0){
140 styler.ColourTo(pos1,SCE_FORTH_COMMENT);
141 parse(')',true);
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);
146 parse(']',true);
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);
151 parse('}',false);
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);
156 parse('"',false);
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);
168 parse(BL,false);
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);
174 parse(BL,false);
175 styler.ColourTo(pos2,SCE_FORTH_PREWORD1);
176 }else if(preword2.InList(buffer)) {
177 styler.ColourTo(pos1,SCE_FORTH_PREWORD2);
178 parse(BL,false);
179 styler.ColourTo(pos2,SCE_FORTH_PREWORD2);
180 parse(BL,false);
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);
186 }
187 }
188#ifdef FORTH_DEBUG
189 fclose(f_debug);
190#endif
191 delete []buffer;
192 return;
193/*
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 );
206 } else {
207 styler.ColourTo(i-1,SCE_FORTH_DEFAULT);
208 }
209*/
210/*
211 chPrev=' ';
212 for (int i = startPos; i < lengthDoc; i++) {
213 char ch = chNext;
214 chNext = styler.SafeGetCharAt(i + 1);
215 if(i!=startPos) chPrev=styler.SafeGetCharAt(i - 1);
216
217 if (styler.IsLeadByte(ch)) {
218 chNext = styler.SafeGetCharAt(i + 2);
219 i++;
220 continue;
221 }
222#ifdef FORTH_DEBUG
223 fprintf(f_debug,"%c %d ",ch,state);
224#endif
225 switch(state) {
226 case SCE_FORTH_DEFAULT:
227 if(is_whitespace(ch)) {
228 // whitespace is simply ignored here...
229 styler.ColourTo(i,SCE_FORTH_DEFAULT);
230 break;
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
241 bufferCount = 0;
242 buffer[bufferCount++] = ch;
243 state = SCE_FORTH_NUMBER;
244 } else if( !is_whitespace(ch)) {
245 // signals the start of an identifier
246 bufferCount = 0;
247 buffer[bufferCount++] = ch;
248 state = SCE_FORTH_IDENTIFIER;
249 } else {
250 // style it the default style..
251 styler.ColourTo(i,SCE_FORTH_DEFAULT);
252 }
253 break;
254
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;
261 } else {
262 styler.ColourTo(i,SCE_FORTH_COMMENT);
263 }
264 break;
265
266 case SCE_FORTH_COMMENT_ML:
267 if( ch == ')') {
268 state = SCE_FORTH_DEFAULT;
269 } else {
270 styler.ColourTo(i+1,SCE_FORTH_COMMENT_ML);
271 }
272 break;
273
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;
278 } else {
279 state = SCE_FORTH_DEFAULT;
280 buffer[bufferCount] = '\0';
281#ifdef FORTH_DEBUG
282 fprintf(f_debug,"\nid %s\n",buffer);
283#endif
284
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 );
301 } else {
302 styler.ColourTo(i-1,SCE_FORTH_DEFAULT);
303 }
304// break;
305// case
306
307 // push back the faulty character
308 chNext = styler[i--];
309 }
310 break;
311
312 case SCE_FORTH_NUMBER:
313 // stay in CONF_NUMBER state until we find a non-numeric
314 if( isdigit(ch) ) {
315 buffer[bufferCount++] = ch;
316 } else {
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--];
323 }
324 break;
325 }
326 }
327#ifdef FORTH_DEBUG
328 fclose(f_debug);
329#endif
330 delete []buffer;
331*/
332}
333
334static void FoldForthDoc(unsigned int, int, int, WordList *[],
335 Accessor &) {
336}
337
338static const char * const forthWordLists[] = {
339 "control keywords",
340 "keywords",
341 "definition words",
342 "prewords with one argument",
343 "prewords with two arguments",
344 "string definition keywords",
345 0,
346 };
347
348LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth",FoldForthDoc,forthWordLists);