Fix variable collision
[TortoiseGit.git] / ext / scintilla / lexers / LexOpal.cxx
blob259417f9bc938ba649fa1fc15c3fca04d824e64b
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 <stdio.h>
10 #include <stdarg.h>
11 #include <assert.h>
12 #include <ctype.h>
14 #include "ILexer.h"
15 #include "Scintilla.h"
16 #include "SciLexer.h"
18 #include "WordList.h"
19 #include "LexAccessor.h"
20 #include "Accessor.h"
21 #include "StyleContext.h"
22 #include "CharacterSet.h"
23 #include "LexerModule.h"
25 #ifdef SCI_NAMESPACE
26 using namespace Scintilla;
27 #endif
29 inline static void getRange( unsigned int start, unsigned int end, Accessor & styler, char * s, unsigned int len )
31 unsigned int i = 0;
32 while( ( i < end - start + 1 ) && ( i < len - 1 ) )
34 s[i] = static_cast<char>( styler[ start + i ] );
35 i++;
37 s[ i ] = '\0';
40 inline bool HandleString( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
42 char ch;
44 // Wait for string to close
45 bool even_backslash_count = true; // Without gaps in between
46 cur++; // Skip initial quote
47 for( ; ; )
49 if( cur >= one_too_much )
51 styler.ColourTo( cur - 1, SCE_OPAL_STRING );
52 return false; // STOP
55 ch = styler.SafeGetCharAt( cur );
56 if( ( ch == '\015' ) || ( ch == '\012' ) ) // Deny multi-line strings
58 styler.ColourTo( cur - 1, SCE_OPAL_STRING );
59 styler.StartSegment( cur );
60 return true;
62 else
64 if( even_backslash_count )
66 if( ch == '"' )
68 styler.ColourTo( cur, SCE_OPAL_STRING );
69 cur++;
70 if( cur >= one_too_much )
72 return false; // STOP
74 else
76 styler.StartSegment( cur );
77 return true;
80 else if( ch == '\\' )
82 even_backslash_count = false;
85 else
87 even_backslash_count = true;
91 cur++;
95 inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
97 char ch;
99 if( could_fail )
101 cur++;
102 if( cur >= one_too_much )
104 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
105 return false; // STOP
108 ch = styler.SafeGetCharAt( cur );
109 if( ch != '*' )
111 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
112 styler.StartSegment( cur );
113 return true;
117 // Wait for comment close
118 cur++;
119 bool star_found = false;
120 for( ; ; )
122 if( cur >= one_too_much )
124 styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_BLOCK );
125 return false; // STOP
128 ch = styler.SafeGetCharAt( cur );
129 if( star_found )
131 if( ch == '/' )
133 styler.ColourTo( cur, SCE_OPAL_COMMENT_BLOCK );
134 cur++;
135 if( cur >= one_too_much )
137 return false; // STOP
139 else
141 styler.StartSegment( cur );
142 return true;
145 else if( ch != '*' )
147 star_found = false;
150 else if( ch == '*' )
152 star_found = true;
154 cur++;
158 inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
160 char ch;
162 if( could_fail )
164 cur++;
165 if( cur >= one_too_much )
167 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
168 return false; // STOP
171 ch = styler.SafeGetCharAt( cur );
172 if( ch != '-' )
174 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
175 styler.StartSegment( cur );
176 return true;
179 cur++;
180 if( cur >= one_too_much )
182 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
183 return false; // STOP
186 ch = styler.SafeGetCharAt( cur );
187 if( ( ch != ' ' ) && ( ch != '\t' ) )
189 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
190 styler.StartSegment( cur );
191 return true;
195 // Wait for end of line
196 bool fifteen_found = false;
198 for( ; ; )
200 cur++;
202 if( cur >= one_too_much )
204 styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
205 return false; // STOP
208 ch = styler.SafeGetCharAt( cur );
209 if( fifteen_found )
212 if( ch == '\012' )
214 // One newline on Windows (015, 012)
216 else
218 // One newline on MAC (015) and another char
221 cur--;
222 styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
223 styler.StartSegment( cur );
224 return true;
226 else
228 if( ch == '\015' )
230 fifteen_found = true;
232 else if( ch == '\012' )
234 // One newline on Linux (012)
235 styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
236 styler.StartSegment( cur );
237 return true;
243 inline bool HandlePar( unsigned int & cur, Accessor & styler )
245 styler.ColourTo( cur, SCE_OPAL_PAR );
247 cur++;
249 styler.StartSegment( cur );
250 return true;
253 inline bool HandleSpace( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
255 char ch;
257 cur++;
258 for( ; ; )
260 if( cur >= one_too_much )
262 styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
263 return false;
266 ch = styler.SafeGetCharAt( cur );
267 switch( ch )
269 case ' ':
270 case '\t':
271 case '\015':
272 case '\012':
273 cur++;
274 break;
276 default:
277 styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
278 styler.StartSegment( cur );
279 return true;
284 inline bool HandleInteger( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
286 char ch;
288 for( ; ; )
290 cur++;
291 if( cur >= one_too_much )
293 styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
294 return false; // STOP
297 ch = styler.SafeGetCharAt( cur );
298 if( !( IsASCII( ch ) && isdigit( ch ) ) )
300 styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
301 styler.StartSegment( cur );
302 return true;
307 inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor & styler, WordList * keywordlists[] )
309 char ch;
310 const unsigned int beg = cur;
312 cur++;
313 for( ; ; )
315 ch = styler.SafeGetCharAt( cur );
316 if( ( ch != '_' ) && ( ch != '-' ) &&
317 !( IsASCII( ch ) && ( islower( ch ) || isupper( ch ) || isdigit( ch ) ) ) ) break;
319 cur++;
320 if( cur >= one_too_much )
322 break;
326 const int ide_len = cur - beg + 1;
327 char * ide = new char[ ide_len ];
328 getRange( beg, cur, styler, ide, ide_len );
330 WordList & keywords = *keywordlists[ 0 ];
331 WordList & classwords = *keywordlists[ 1 ];
333 if( keywords.InList( ide ) ) // Keyword
335 delete [] ide;
337 styler.ColourTo( cur - 1, SCE_OPAL_KEYWORD );
338 if( cur >= one_too_much )
340 return false; // STOP
342 else
344 styler.StartSegment( cur );
345 return true;
348 else if( classwords.InList( ide ) ) // Sort
350 delete [] ide;
352 styler.ColourTo( cur - 1, SCE_OPAL_SORT );
353 if( cur >= one_too_much )
355 return false; // STOP
357 else
359 styler.StartSegment( cur );
360 return true;
363 else if( !strcmp( ide, "true" ) || !strcmp( ide, "false" ) ) // Bool const
365 delete [] ide;
367 styler.ColourTo( cur - 1, SCE_OPAL_BOOL_CONST );
368 if( cur >= one_too_much )
370 return false; // STOP
372 else
374 styler.StartSegment( cur );
375 return true;
378 else // Unknown keyword
380 delete [] ide;
382 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
383 if( cur >= one_too_much )
385 return false; // STOP
387 else
389 styler.StartSegment( cur );
390 return true;
396 inline bool HandleSkip( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
398 cur++;
399 styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
400 if( cur >= one_too_much )
402 return false; // STOP
404 else
406 styler.StartSegment( cur );
407 return true;
411 static void ColouriseOpalDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor & styler )
413 styler.StartAt( startPos );
414 styler.StartSegment( startPos );
416 unsigned int & cur = startPos;
417 const unsigned int one_too_much = startPos + length;
419 int state = initStyle;
421 for( ; ; )
423 switch( state )
425 case SCE_OPAL_KEYWORD:
426 case SCE_OPAL_SORT:
427 if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
428 state = SCE_OPAL_DEFAULT;
429 break;
431 case SCE_OPAL_INTEGER:
432 if( !HandleInteger( cur, one_too_much, styler ) ) return;
433 state = SCE_OPAL_DEFAULT;
434 break;
436 case SCE_OPAL_COMMENT_BLOCK:
437 if( !HandleCommentBlock( cur, one_too_much, styler, false ) ) return;
438 state = SCE_OPAL_DEFAULT;
439 break;
441 case SCE_OPAL_COMMENT_LINE:
442 if( !HandleCommentLine( cur, one_too_much, styler, false ) ) return;
443 state = SCE_OPAL_DEFAULT;
444 break;
446 case SCE_OPAL_STRING:
447 if( !HandleString( cur, one_too_much, styler ) ) return;
448 state = SCE_OPAL_DEFAULT;
449 break;
451 default: // SCE_OPAL_DEFAULT:
453 char ch = styler.SafeGetCharAt( cur );
455 switch( ch )
457 // String
458 case '"':
459 if( !HandleString( cur, one_too_much, styler ) ) return;
460 break;
462 // Comment block
463 case '/':
464 if( !HandleCommentBlock( cur, one_too_much, styler, true ) ) return;
465 break;
467 // Comment line
468 case '-':
469 if( !HandleCommentLine( cur, one_too_much, styler, true ) ) return;
470 break;
472 // Par
473 case '(':
474 case ')':
475 case '[':
476 case ']':
477 case '{':
478 case '}':
479 if( !HandlePar( cur, styler ) ) return;
480 break;
482 // Whitespace
483 case ' ':
484 case '\t':
485 case '\015':
486 case '\012':
487 if( !HandleSpace( cur, one_too_much, styler ) ) return;
488 break;
490 default:
492 // Integer
493 if( IsASCII( ch ) && isdigit( ch ) )
495 if( !HandleInteger( cur, one_too_much, styler ) ) return;
498 // Keyword
499 else if( IsASCII( ch ) && ( islower( ch ) || isupper( ch ) ) )
501 if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
505 // Skip
506 else
508 if( !HandleSkip( cur, one_too_much, styler ) ) return;
513 break;
519 static const char * const opalWordListDesc[] = {
520 "Keywords",
521 "Sorts",
525 LexerModule lmOpal(SCLEX_OPAL, ColouriseOpalDoc, "opal", NULL, opalWordListDesc);