Add an UI to enable/disable specific overlay handlers.
[TortoiseGit.git] / ext / scintilla / src / LexOpal.cxx
blob168c6fc5f7163520fc9a38e5bc15bb4c3e7127ee
1 // Scintilla source code edit control
2 /** @file LexOpal.cxx
3 ** Lexer for OPAL (functional language similar to Haskell)
4 ** Written by Sebastian Pipping <webmaster@hartwork.org>
5 **/
7 #include <stdlib.h>
8 #include <string.h>
9 #include <ctype.h>
10 #include <stdio.h>
11 #include <stdarg.h>
13 #include "Platform.h"
15 #include "PropSet.h"
16 #include "Accessor.h"
17 #include "KeyWords.h"
18 #include "Scintilla.h"
19 #include "SciLexer.h"
20 #include "StyleContext.h"
22 #ifdef SCI_NAMESPACE
23 using namespace Scintilla;
24 #endif
26 inline static void getRange( unsigned int start, unsigned int end, Accessor & styler, char * s, unsigned int len )
28 unsigned int i = 0;
29 while( ( i < end - start + 1 ) && ( i < len - 1 ) )
31 s[i] = static_cast<char>( styler[ start + i ] );
32 i++;
34 s[ i ] = '\0';
37 inline bool HandleString( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
39 char ch;
41 // Wait for string to close
42 bool even_backslash_count = true; // Without gaps in between
43 cur++; // Skip initial quote
44 for( ; ; )
46 if( cur >= one_too_much )
48 styler.ColourTo( cur - 1, SCE_OPAL_STRING );
49 return false; // STOP
52 ch = styler.SafeGetCharAt( cur );
53 if( ( ch == '\015' ) || ( ch == '\012' ) ) // Deny multi-line strings
55 styler.ColourTo( cur - 1, SCE_OPAL_STRING );
56 styler.StartSegment( cur );
57 return true;
59 else
61 if( even_backslash_count )
63 if( ch == '"' )
65 styler.ColourTo( cur, SCE_OPAL_STRING );
66 cur++;
67 if( cur >= one_too_much )
69 return false; // STOP
71 else
73 styler.StartSegment( cur );
74 return true;
77 else if( ch == '\\' )
79 even_backslash_count = false;
82 else
84 even_backslash_count = true;
88 cur++;
92 inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
94 char ch;
96 if( could_fail )
98 cur++;
99 if( cur >= one_too_much )
101 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
102 return false; // STOP
105 ch = styler.SafeGetCharAt( cur );
106 if( ch != '*' )
108 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
109 styler.StartSegment( cur );
110 return true;
114 // Wait for comment close
115 cur++;
116 bool star_found = false;
117 for( ; ; )
119 if( cur >= one_too_much )
121 styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_BLOCK );
122 return false; // STOP
125 ch = styler.SafeGetCharAt( cur );
126 if( star_found )
128 if( ch == '/' )
130 styler.ColourTo( cur, SCE_OPAL_COMMENT_BLOCK );
131 cur++;
132 if( cur >= one_too_much )
134 return false; // STOP
136 else
138 styler.StartSegment( cur );
139 return true;
142 else if( ch != '*' )
144 star_found = false;
147 else if( ch == '*' )
149 star_found = true;
151 cur++;
155 inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
157 char ch;
159 if( could_fail )
161 cur++;
162 if( cur >= one_too_much )
164 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
165 return false; // STOP
168 ch = styler.SafeGetCharAt( cur );
169 if( ch != '-' )
171 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
172 styler.StartSegment( cur );
173 return true;
176 cur++;
177 if( cur >= one_too_much )
179 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
180 return false; // STOP
183 ch = styler.SafeGetCharAt( cur );
184 if( ( ch != ' ' ) && ( ch != '\t' ) )
186 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
187 styler.StartSegment( cur );
188 return true;
192 // Wait for end of line
193 bool fifteen_found = false;
195 for( ; ; )
197 cur++;
199 if( cur >= one_too_much )
201 styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
202 return false; // STOP
205 ch = styler.SafeGetCharAt( cur );
206 if( fifteen_found )
209 if( ch == '\012' )
211 // One newline on Windows (015, 012)
213 else
215 // One newline on MAC (015) and another char
218 cur--;
219 styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
220 styler.StartSegment( cur );
221 return true;
223 else
225 if( ch == '\015' )
227 fifteen_found = true;
229 else if( ch == '\012' )
231 // One newline on Linux (012)
232 styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
233 styler.StartSegment( cur );
234 return true;
240 inline bool HandlePar( unsigned int & cur, Accessor & styler )
242 styler.ColourTo( cur, SCE_OPAL_PAR );
244 cur++;
246 styler.StartSegment( cur );
247 return true;
250 inline bool HandleSpace( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
252 char ch;
254 cur++;
255 for( ; ; )
257 if( cur >= one_too_much )
259 styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
260 return false;
263 ch = styler.SafeGetCharAt( cur );
264 switch( ch )
266 case ' ':
267 case '\t':
268 case '\015':
269 case '\012':
270 cur++;
271 break;
273 default:
274 styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
275 styler.StartSegment( cur );
276 return true;
281 inline bool HandleInteger( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
283 char ch;
285 for( ; ; )
287 cur++;
288 if( cur >= one_too_much )
290 styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
291 return false; // STOP
294 ch = styler.SafeGetCharAt( cur );
295 if( !isdigit( ch ) )
297 styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
298 styler.StartSegment( cur );
299 return true;
304 inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor & styler, WordList * keywordlists[] )
306 char ch;
307 const unsigned int beg = cur;
309 cur++;
310 for( ; ; )
312 ch = styler.SafeGetCharAt( cur );
313 if( ( ch != '_' ) && ( ch != '-' ) &&
314 !islower( ch ) && !isupper( ch ) && !isdigit( ch ) ) break;
316 cur++;
317 if( cur >= one_too_much )
319 break;
323 const int ide_len = cur - beg + 1;
324 char * ide = new char[ ide_len ];
325 getRange( beg, cur, styler, ide, ide_len );
327 WordList & keywords = *keywordlists[ 0 ];
328 WordList & classwords = *keywordlists[ 1 ];
330 if( keywords.InList( ide ) ) // Keyword
332 delete [] ide;
334 styler.ColourTo( cur - 1, SCE_OPAL_KEYWORD );
335 if( cur >= one_too_much )
337 return false; // STOP
339 else
341 styler.StartSegment( cur );
342 return true;
345 else if( classwords.InList( ide ) ) // Sort
347 delete [] ide;
349 styler.ColourTo( cur - 1, SCE_OPAL_SORT );
350 if( cur >= one_too_much )
352 return false; // STOP
354 else
356 styler.StartSegment( cur );
357 return true;
360 else if( !strcmp( ide, "true" ) || !strcmp( ide, "false" ) ) // Bool const
362 delete [] ide;
364 styler.ColourTo( cur - 1, SCE_OPAL_BOOL_CONST );
365 if( cur >= one_too_much )
367 return false; // STOP
369 else
371 styler.StartSegment( cur );
372 return true;
375 else // Unknown keyword
377 delete [] ide;
379 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
380 if( cur >= one_too_much )
382 return false; // STOP
384 else
386 styler.StartSegment( cur );
387 return true;
393 inline bool HandleSkip( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
395 cur++;
396 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
397 if( cur >= one_too_much )
399 return false; // STOP
401 else
403 styler.StartSegment( cur );
404 return true;
408 static void ColouriseOpalDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor & styler )
410 styler.StartAt( startPos );
411 styler.StartSegment( startPos );
413 unsigned int & cur = startPos;
414 const unsigned int one_too_much = startPos + length;
416 int state = initStyle;
418 for( ; ; )
420 switch( state )
422 case SCE_OPAL_KEYWORD:
423 case SCE_OPAL_SORT:
424 if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
425 state = SCE_OPAL_DEFAULT;
426 break;
428 case SCE_OPAL_INTEGER:
429 if( !HandleInteger( cur, one_too_much, styler ) ) return;
430 state = SCE_OPAL_DEFAULT;
431 break;
433 case SCE_OPAL_COMMENT_BLOCK:
434 if( !HandleCommentBlock( cur, one_too_much, styler, false ) ) return;
435 state = SCE_OPAL_DEFAULT;
436 break;
438 case SCE_OPAL_COMMENT_LINE:
439 if( !HandleCommentLine( cur, one_too_much, styler, false ) ) return;
440 state = SCE_OPAL_DEFAULT;
441 break;
443 case SCE_OPAL_STRING:
444 if( !HandleString( cur, one_too_much, styler ) ) return;
445 state = SCE_OPAL_DEFAULT;
446 break;
448 default: // SCE_OPAL_DEFAULT:
450 char ch = styler.SafeGetCharAt( cur );
452 switch( ch )
454 // String
455 case '"':
456 if( !HandleString( cur, one_too_much, styler ) ) return;
457 break;
459 // Comment block
460 case '/':
461 if( !HandleCommentBlock( cur, one_too_much, styler, true ) ) return;
462 break;
464 // Comment line
465 case '-':
466 if( !HandleCommentLine( cur, one_too_much, styler, true ) ) return;
467 break;
469 // Par
470 case '(':
471 case ')':
472 case '[':
473 case ']':
474 case '{':
475 case '}':
476 if( !HandlePar( cur, styler ) ) return;
477 break;
479 // Whitespace
480 case ' ':
481 case '\t':
482 case '\015':
483 case '\012':
484 if( !HandleSpace( cur, one_too_much, styler ) ) return;
485 break;
487 default:
489 // Integer
490 if( isdigit( ch ) )
492 if( !HandleInteger( cur, one_too_much, styler ) ) return;
495 // Keyword
496 else if( islower( ch ) || isupper( ch ) )
498 if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
502 // Skip
503 else
505 if( !HandleSkip( cur, one_too_much, styler ) ) return;
510 break;
516 static const char * const opalWordListDesc[] = {
517 "Keywords",
518 "Sorts",
522 LexerModule lmOpal(SCLEX_OPAL, ColouriseOpalDoc, "opal", NULL, opalWordListDesc);