]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/lexers/LexOpal.cxx
1 // Scintilla source code edit control
3 ** Lexer for OPAL (functional language similar to Haskell)
4 ** Written by Sebastian Pipping <webmaster@hartwork.org>
15 #include "Scintilla.h"
19 #include "LexAccessor.h"
21 #include "StyleContext.h"
22 #include "CharacterSet.h"
23 #include "LexerModule.h"
26 using namespace Scintilla
;
29 inline static void getRange( unsigned int start
, unsigned int end
, Accessor
& styler
, char * s
, unsigned int len
)
32 while( ( i
< end
- start
+ 1 ) && ( i
< len
- 1 ) )
34 s
[i
] = static_cast<char>( styler
[ start
+ i
] );
40 inline bool HandleString( unsigned int & cur
, unsigned int one_too_much
, Accessor
& styler
)
44 // Wait for string to close
45 bool even_backslash_count
= true; // Without gaps in between
46 cur
++; // Skip initial quote
49 if( cur
>= one_too_much
)
51 styler
.ColourTo( cur
- 1, SCE_OPAL_STRING
);
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
);
64 if( even_backslash_count
)
68 styler
.ColourTo( cur
, SCE_OPAL_STRING
);
70 if( cur
>= one_too_much
)
76 styler
.StartSegment( cur
);
82 even_backslash_count
= false;
87 even_backslash_count
= true;
95 inline bool HandleCommentBlock( unsigned int & cur
, unsigned int one_too_much
, Accessor
& styler
, bool could_fail
)
102 if( cur
>= one_too_much
)
104 styler
.ColourTo( cur
- 1, SCE_OPAL_DEFAULT
);
105 return false; // STOP
108 ch
= styler
.SafeGetCharAt( cur
);
111 styler
.ColourTo( cur
- 1, SCE_OPAL_DEFAULT
);
112 styler
.StartSegment( cur
);
117 // Wait for comment close
119 bool star_found
= false;
122 if( cur
>= one_too_much
)
124 styler
.ColourTo( cur
- 1, SCE_OPAL_COMMENT_BLOCK
);
125 return false; // STOP
128 ch
= styler
.SafeGetCharAt( cur
);
133 styler
.ColourTo( cur
, SCE_OPAL_COMMENT_BLOCK
);
135 if( cur
>= one_too_much
)
137 return false; // STOP
141 styler
.StartSegment( cur
);
158 inline bool HandleCommentLine( unsigned int & cur
, unsigned int one_too_much
, Accessor
& styler
, bool could_fail
)
165 if( cur
>= one_too_much
)
167 styler
.ColourTo( cur
- 1, SCE_OPAL_DEFAULT
);
168 return false; // STOP
171 ch
= styler
.SafeGetCharAt( cur
);
174 styler
.ColourTo( cur
- 1, SCE_OPAL_DEFAULT
);
175 styler
.StartSegment( 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
);
195 // Wait for end of line
196 bool fifteen_found
= false;
202 if( cur
>= one_too_much
)
204 styler
.ColourTo( cur
- 1, SCE_OPAL_COMMENT_LINE
);
205 return false; // STOP
208 ch
= styler
.SafeGetCharAt( cur
);
214 // One newline on Windows (015, 012)
218 // One newline on MAC (015) and another char
222 styler
.ColourTo( cur
- 1, SCE_OPAL_COMMENT_LINE
);
223 styler
.StartSegment( cur
);
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
);
243 inline bool HandlePar( unsigned int & cur
, Accessor
& styler
)
245 styler
.ColourTo( cur
, SCE_OPAL_PAR
);
249 styler
.StartSegment( cur
);
253 inline bool HandleSpace( unsigned int & cur
, unsigned int one_too_much
, Accessor
& styler
)
260 if( cur
>= one_too_much
)
262 styler
.ColourTo( cur
- 1, SCE_OPAL_SPACE
);
266 ch
= styler
.SafeGetCharAt( cur
);
277 styler
.ColourTo( cur
- 1, SCE_OPAL_SPACE
);
278 styler
.StartSegment( cur
);
284 inline bool HandleInteger( unsigned int & cur
, unsigned int one_too_much
, Accessor
& styler
)
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
);
307 inline bool HandleWord( unsigned int & cur
, unsigned int one_too_much
, Accessor
& styler
, WordList
* keywordlists
[] )
310 const unsigned int beg
= cur
;
315 ch
= styler
.SafeGetCharAt( cur
);
316 if( ( ch
!= '_' ) && ( ch
!= '-' ) &&
317 !( isascii( ch
) && ( islower( ch
) || isupper( ch
) || isdigit( ch
) ) ) ) break;
320 if( cur
>= one_too_much
)
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
337 styler
.ColourTo( cur
- 1, SCE_OPAL_KEYWORD
);
338 if( cur
>= one_too_much
)
340 return false; // STOP
344 styler
.StartSegment( cur
);
348 else if( classwords
.InList( ide
) ) // Sort
352 styler
.ColourTo( cur
- 1, SCE_OPAL_SORT
);
353 if( cur
>= one_too_much
)
355 return false; // STOP
359 styler
.StartSegment( cur
);
363 else if( !strcmp( ide
, "true" ) || !strcmp( ide
, "false" ) ) // Bool const
367 styler
.ColourTo( cur
- 1, SCE_OPAL_BOOL_CONST
);
368 if( cur
>= one_too_much
)
370 return false; // STOP
374 styler
.StartSegment( cur
);
378 else // Unknown keyword
382 styler
.ColourTo( cur
- 1, SCE_OPAL_DEFAULT
);
383 if( cur
>= one_too_much
)
385 return false; // STOP
389 styler
.StartSegment( cur
);
396 inline bool HandleSkip( unsigned int & cur
, unsigned int one_too_much
, Accessor
& styler
)
399 styler
.ColourTo( cur
- 1, SCE_OPAL_DEFAULT
);
400 if( cur
>= one_too_much
)
402 return false; // STOP
406 styler
.StartSegment( cur
);
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
;
425 case SCE_OPAL_KEYWORD
:
427 if( !HandleWord( cur
, one_too_much
, styler
, keywordlists
) ) return;
428 state
= SCE_OPAL_DEFAULT
;
431 case SCE_OPAL_INTEGER
:
432 if( !HandleInteger( cur
, one_too_much
, styler
) ) return;
433 state
= SCE_OPAL_DEFAULT
;
436 case SCE_OPAL_COMMENT_BLOCK
:
437 if( !HandleCommentBlock( cur
, one_too_much
, styler
, false ) ) return;
438 state
= SCE_OPAL_DEFAULT
;
441 case SCE_OPAL_COMMENT_LINE
:
442 if( !HandleCommentLine( cur
, one_too_much
, styler
, false ) ) return;
443 state
= SCE_OPAL_DEFAULT
;
446 case SCE_OPAL_STRING
:
447 if( !HandleString( cur
, one_too_much
, styler
) ) return;
448 state
= SCE_OPAL_DEFAULT
;
451 default: // SCE_OPAL_DEFAULT:
453 char ch
= styler
.SafeGetCharAt( cur
);
459 if( !HandleString( cur
, one_too_much
, styler
) ) return;
464 if( !HandleCommentBlock( cur
, one_too_much
, styler
, true ) ) return;
469 if( !HandleCommentLine( cur
, one_too_much
, styler
, true ) ) return;
479 if( !HandlePar( cur
, styler
) ) return;
487 if( !HandleSpace( cur
, one_too_much
, styler
) ) return;
493 if( isascii( ch
) && isdigit( ch
) )
495 if( !HandleInteger( cur
, one_too_much
, styler
) ) return;
499 else if( isascii( ch
) && ( islower( ch
) || isupper( ch
) ) )
501 if( !HandleWord( cur
, one_too_much
, styler
, keywordlists
) ) return;
508 if( !HandleSkip( cur
, one_too_much
, styler
) ) return;
519 static const char * const opalWordListDesc
[] = {
525 LexerModule
lmOpal(SCLEX_OPAL
, ColouriseOpalDoc
, "opal", NULL
, opalWordListDesc
);