1
// Scintilla source code edit control
3
** Lexer for OPAL (functional language similar to Haskell)
4
** Written by Sebastian Pipping <webmaster@hartwork.org>
18
#include "Scintilla.h"
20
#include "StyleContext.h"
23
using namespace Scintilla;
26
inline static void getRange( unsigned int start, unsigned int end, Accessor & styler, char * s, unsigned int len )
29
while( ( i < end - start + 1 ) && ( i < len - 1 ) )
31
s[i] = static_cast<char>( styler[ start + i ] );
37
inline bool HandleString( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
41
// Wait for string to close
42
bool even_backslash_count = true; // Without gaps in between
43
cur++; // Skip initial quote
46
if( cur >= one_too_much )
48
styler.ColourTo( cur - 1, SCE_OPAL_STRING );
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 );
61
if( even_backslash_count )
65
styler.ColourTo( cur, SCE_OPAL_STRING );
67
if( cur >= one_too_much )
73
styler.StartSegment( cur );
79
even_backslash_count = false;
84
even_backslash_count = true;
92
inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
99
if( cur >= one_too_much )
101
styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
102
return false; // STOP
105
ch = styler.SafeGetCharAt( cur );
108
styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
109
styler.StartSegment( cur );
114
// Wait for comment close
116
bool star_found = false;
119
if( cur >= one_too_much )
121
styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_BLOCK );
122
return false; // STOP
125
ch = styler.SafeGetCharAt( cur );
130
styler.ColourTo( cur, SCE_OPAL_COMMENT_BLOCK );
132
if( cur >= one_too_much )
134
return false; // STOP
138
styler.StartSegment( cur );
155
inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
162
if( cur >= one_too_much )
164
styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
165
return false; // STOP
168
ch = styler.SafeGetCharAt( cur );
171
styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
172
styler.StartSegment( 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 );
192
// Wait for end of line
193
bool fifteen_found = false;
199
if( cur >= one_too_much )
201
styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
202
return false; // STOP
205
ch = styler.SafeGetCharAt( cur );
211
// One newline on Windows (015, 012)
215
// One newline on MAC (015) and another char
219
styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
220
styler.StartSegment( cur );
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 );
240
inline bool HandlePar( unsigned int & cur, Accessor & styler )
242
styler.ColourTo( cur, SCE_OPAL_PAR );
246
styler.StartSegment( cur );
250
inline bool HandleSpace( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
257
if( cur >= one_too_much )
259
styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
263
ch = styler.SafeGetCharAt( cur );
274
styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
275
styler.StartSegment( cur );
281
inline bool HandleInteger( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
288
if( cur >= one_too_much )
290
styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
291
return false; // STOP
294
ch = styler.SafeGetCharAt( cur );
297
styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
298
styler.StartSegment( cur );
304
inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor & styler, WordList * keywordlists[] )
307
const unsigned int beg = cur;
312
ch = styler.SafeGetCharAt( cur );
313
if( ( ch != '_' ) && ( ch != '-' ) &&
314
!islower( ch ) && !isupper( ch ) && !isdigit( ch ) ) break;
317
if( cur >= one_too_much )
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
334
styler.ColourTo( cur - 1, SCE_OPAL_KEYWORD );
335
if( cur >= one_too_much )
337
return false; // STOP
341
styler.StartSegment( cur );
345
else if( classwords.InList( ide ) ) // Sort
349
styler.ColourTo( cur - 1, SCE_OPAL_SORT );
350
if( cur >= one_too_much )
352
return false; // STOP
356
styler.StartSegment( cur );
360
else if( !strcmp( ide, "true" ) || !strcmp( ide, "false" ) ) // Bool const
364
styler.ColourTo( cur - 1, SCE_OPAL_BOOL_CONST );
365
if( cur >= one_too_much )
367
return false; // STOP
371
styler.StartSegment( cur );
375
else // Unknown keyword
379
styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
380
if( cur >= one_too_much )
382
return false; // STOP
386
styler.StartSegment( cur );
393
inline bool HandleSkip( unsigned int & cur, unsigned int one_too_much, Accessor & styler )
396
styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
397
if( cur >= one_too_much )
399
return false; // STOP
403
styler.StartSegment( cur );
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;
422
case SCE_OPAL_KEYWORD:
424
if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
425
state = SCE_OPAL_DEFAULT;
428
case SCE_OPAL_INTEGER:
429
if( !HandleInteger( cur, one_too_much, styler ) ) return;
430
state = SCE_OPAL_DEFAULT;
433
case SCE_OPAL_COMMENT_BLOCK:
434
if( !HandleCommentBlock( cur, one_too_much, styler, false ) ) return;
435
state = SCE_OPAL_DEFAULT;
438
case SCE_OPAL_COMMENT_LINE:
439
if( !HandleCommentLine( cur, one_too_much, styler, false ) ) return;
440
state = SCE_OPAL_DEFAULT;
443
case SCE_OPAL_STRING:
444
if( !HandleString( cur, one_too_much, styler ) ) return;
445
state = SCE_OPAL_DEFAULT;
448
default: // SCE_OPAL_DEFAULT:
450
char ch = styler.SafeGetCharAt( cur );
456
if( !HandleString( cur, one_too_much, styler ) ) return;
461
if( !HandleCommentBlock( cur, one_too_much, styler, true ) ) return;
466
if( !HandleCommentLine( cur, one_too_much, styler, true ) ) return;
476
if( !HandlePar( cur, styler ) ) return;
484
if( !HandleSpace( cur, one_too_much, styler ) ) return;
492
if( !HandleInteger( cur, one_too_much, styler ) ) return;
496
else if( islower( ch ) || isupper( ch ) )
498
if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
505
if( !HandleSkip( cur, one_too_much, styler ) ) return;
516
static const char * const opalWordListDesc[] = {
522
LexerModule lmOpal(SCLEX_OPAL, ColouriseOpalDoc, "opal", NULL, opalWordListDesc);