]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/LexTADS3.cxx
1 // Scintilla source code edit control
5 /* Copyright 2005 by Michael Cartmell
6 * Parts copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
7 * In particular FoldTADS3Doc is derived from FoldCppDoc
8 * The License.txt file describes the conditions under which this software may
13 * TADS3 is a language designed by Michael J. Roberts for the writing of text
14 * based games. TADS comes from Text Adventure Development System. It has good
15 * support for the processing and outputting of formatted text and much of a
16 * TADS program listing consists of strings.
18 * TADS has two types of strings, those enclosed in single quotes (') and those
19 * enclosed in double quotes ("). These strings have different symantics and
20 * can be given different highlighting if desired.
22 * There can be embedded within both types of strings html tags
23 * ( <tag key=value> ), library directives ( <.directive> ), and message
24 * parameters ( {The doctor's/his} ).
26 * Double quoted strings can also contain interpolated expressions
27 * ( << rug.moved ? ' and a hole in the floor. ' : nil >> ). These expressions
28 * may themselves contain single or double quoted strings, although the double
29 * quoted strings may not contain interpolated expressions.
31 * These embedded constructs influence the output and formatting and are an
32 * important part of a program and require highlighting.
35 * http://www.tads.org/
48 #include "StyleContext.h"
50 #include "Scintilla.h"
53 static const int T3_SINGLE_QUOTE
= 1;
54 static const int T3_INT_EXPRESSION
= 2;
56 static inline bool IsEOL(const int ch
, const int chNext
) {
57 return (ch
== '\r' && chNext
!= '\n') || (ch
== '\n');
60 static inline bool IsASpaceOrTab(const int ch
) {
61 return ch
== ' ' || ch
== '\t';
64 static inline bool IsATADS3Operator(const int ch
) {
65 return ch
== '=' || ch
== '{' || ch
== '}' || ch
== '(' || ch
== ')'
66 || ch
== '[' || ch
== ']' || ch
== ',' || ch
== ':' || ch
== ';'
67 || ch
== '+' || ch
== '-' || ch
== '*' || ch
== '/' || ch
== '%'
68 || ch
== '?' || ch
== '!' || ch
== '<' || ch
== '>' || ch
== '|'
69 || ch
== '@' || ch
== '&' || ch
== '~';
72 static inline bool IsAWordChar(const int ch
) {
73 return isalnum(ch
) || ch
== '_' || ch
== '.';
76 static inline bool IsAWordStart(const int ch
) {
77 return isalpha(ch
) || ch
== '_';
80 static inline bool IsAHexDigit(const int ch
) {
81 int lch
= tolower(ch
);
82 return isdigit(lch
) || lch
== 'a' || lch
== 'b' || lch
== 'c'
83 || lch
== 'd' || lch
== 'e' || lch
== 'f';
86 static inline bool IsAnHTMLChar(int ch
) {
87 return isalnum(ch
) || ch
== '-' || ch
== '_' || ch
== '.';
90 static inline bool IsADirectiveChar(int ch
) {
91 return isalnum(ch
) || isspace(ch
) || ch
== '-' || ch
== '/';
94 static inline bool IsANumberStart(StyleContext
&sc
) {
96 || (!isdigit(sc
.chPrev
) && sc
.ch
== '.' && isdigit(sc
.chNext
));
99 inline static void ColouriseTADS3Operator(StyleContext
&sc
) {
100 int initState
= sc
.state
;
101 sc
.SetState(SCE_T3_OPERATOR
);
102 sc
.ForwardSetState(initState
);
105 static void ColouriseTADSHTMLString(StyleContext
&sc
, int &lineState
) {
106 int endState
= sc
.state
;
108 if (endState
== SCE_T3_HTML_STRING
) {
109 if (lineState
&T3_SINGLE_QUOTE
) {
110 endState
= SCE_T3_S_STRING
;
112 } else if (lineState
&T3_INT_EXPRESSION
) {
113 endState
= SCE_T3_X_STRING
;
116 endState
= SCE_T3_D_STRING
;
120 sc
.SetState(SCE_T3_HTML_STRING
);
123 int chString
= chQuote
== '"'? '\'': '"';
126 if (IsEOL(sc
.ch
, sc
.chNext
)) {
129 if (sc
.ch
== chQuote
) {
130 sc
.ForwardSetState(endState
);
133 if (sc
.ch
== chString
) {
134 sc
.SetState(endState
);
137 if (sc
.Match('\\', static_cast<char>(chQuote
))
138 || sc
.Match('\\', static_cast<char>(chString
))) {
146 static void ColouriseTADS3HTMLTagStart(StyleContext
&sc
) {
147 sc
.SetState(SCE_T3_HTML_TAG
);
152 while (IsAnHTMLChar(sc
.ch
)) {
157 static void ColouriseTADS3HTMLTag(StyleContext
&sc
, int &lineState
) {
158 int endState
= sc
.state
;
162 case SCE_T3_S_STRING
:
163 ColouriseTADS3HTMLTagStart(sc
);
164 sc
.SetState(SCE_T3_HTML_DEFAULT
);
168 case SCE_T3_D_STRING
:
169 case SCE_T3_X_STRING
:
170 ColouriseTADS3HTMLTagStart(sc
);
171 sc
.SetState(SCE_T3_HTML_DEFAULT
);
173 case SCE_T3_HTML_DEFAULT
:
174 if (lineState
&T3_SINGLE_QUOTE
) {
175 endState
= SCE_T3_S_STRING
;
178 } else if (lineState
&T3_INT_EXPRESSION
) {
179 endState
= SCE_T3_X_STRING
;
181 endState
= SCE_T3_D_STRING
;
187 if (IsEOL(sc
.ch
, sc
.chNext
)) {
190 if (sc
.Match('/', '>')) {
191 sc
.SetState(SCE_T3_HTML_TAG
);
193 sc
.SetState(endState
);
197 sc
.SetState(SCE_T3_HTML_TAG
);
198 sc
.ForwardSetState(endState
);
201 if (sc
.ch
== chQuote
) {
202 sc
.SetState(endState
);
205 if (sc
.ch
== chString
) {
206 ColouriseTADSHTMLString(sc
, lineState
);
207 } else if (sc
.ch
== '=') {
208 ColouriseTADS3Operator(sc
);
215 static void ColouriseTADS3Keyword(StyleContext
&sc
,
216 WordList
*keywordlists
[], unsigned int endPos
) {
218 WordList
&keywords
= *keywordlists
[0];
219 WordList
&userwords1
= *keywordlists
[1];
220 WordList
&userwords2
= *keywordlists
[2];
221 WordList
&userwords3
= *keywordlists
[3];
222 int initState
= sc
.state
;
223 sc
.SetState(SCE_T3_IDENTIFIER
);
224 while (sc
.More() && (IsAWordChar(sc
.ch
))) {
227 sc
.GetCurrent(s
, sizeof(s
));
228 if ( strcmp(s
, "is") == 0 || strcmp(s
, "not") == 0) {
229 // have to find if "in" is next
231 while (n
+ sc
.currentPos
< endPos
&& IsASpaceOrTab(sc
.GetRelative(n
)))
233 if (sc
.GetRelative(n
) == 'i' && sc
.GetRelative(n
+1) == 'n') {
235 sc
.ChangeState(SCE_T3_KEYWORD
);
237 } else if (keywords
.InList(s
)) {
238 sc
.ChangeState(SCE_T3_KEYWORD
);
239 } else if (userwords3
.InList(s
)) {
240 sc
.ChangeState(SCE_T3_USER3
);
241 } else if (userwords2
.InList(s
)) {
242 sc
.ChangeState(SCE_T3_USER2
);
243 } else if (userwords1
.InList(s
)) {
244 sc
.ChangeState(SCE_T3_USER1
);
246 sc
.SetState(initState
);
249 static void ColouriseTADS3MsgParam(StyleContext
&sc
, int &lineState
) {
250 int endState
= sc
.state
;
253 case SCE_T3_S_STRING
:
254 sc
.SetState(SCE_T3_MSG_PARAM
);
258 case SCE_T3_D_STRING
:
259 case SCE_T3_X_STRING
:
260 sc
.SetState(SCE_T3_MSG_PARAM
);
263 case SCE_T3_MSG_PARAM
:
264 if (lineState
&T3_SINGLE_QUOTE
) {
265 endState
= SCE_T3_S_STRING
;
267 } else if (lineState
&T3_INT_EXPRESSION
) {
268 endState
= SCE_T3_X_STRING
;
270 endState
= SCE_T3_D_STRING
;
274 while (sc
.More() && sc
.ch
!= '}' && sc
.ch
!= chQuote
) {
275 if (IsEOL(sc
.ch
, sc
.chNext
)) {
283 if (sc
.ch
== chQuote
) {
284 sc
.SetState(endState
);
286 sc
.ForwardSetState(endState
);
290 static void ColouriseTADS3LibDirective(StyleContext
&sc
, int &lineState
) {
291 int initState
= sc
.state
;
294 case SCE_T3_S_STRING
:
295 sc
.SetState(SCE_T3_LIB_DIRECTIVE
);
299 case SCE_T3_D_STRING
:
300 sc
.SetState(SCE_T3_LIB_DIRECTIVE
);
303 case SCE_T3_LIB_DIRECTIVE
:
304 if (lineState
&T3_SINGLE_QUOTE
) {
305 initState
= SCE_T3_S_STRING
;
308 initState
= SCE_T3_D_STRING
;
312 while (sc
.More() && IsADirectiveChar(sc
.ch
)) {
313 if (IsEOL(sc
.ch
, sc
.chNext
)) {
318 if (sc
.ch
== '>' || !sc
.More()) {
319 sc
.ForwardSetState(initState
);
320 } else if (sc
.ch
== chQuote
) {
321 sc
.SetState(initState
);
323 sc
.ChangeState(initState
);
328 static void ColouriseTADS3String(StyleContext
&sc
, int &lineState
) {
330 int endState
= sc
.state
;
333 case SCE_T3_X_DEFAULT
:
334 if (chQuote
== '"') {
335 if (sc
.state
== SCE_T3_DEFAULT
) {
336 sc
.SetState(SCE_T3_D_STRING
);
338 sc
.SetState(SCE_T3_X_STRING
);
340 lineState
&= ~T3_SINGLE_QUOTE
;
342 sc
.SetState(SCE_T3_S_STRING
);
343 lineState
|= T3_SINGLE_QUOTE
;
347 case SCE_T3_S_STRING
:
349 endState
= lineState
&T3_INT_EXPRESSION
?
350 SCE_T3_X_DEFAULT
: SCE_T3_DEFAULT
;
352 case SCE_T3_D_STRING
:
354 endState
= SCE_T3_DEFAULT
;
356 case SCE_T3_X_STRING
:
358 endState
= SCE_T3_X_DEFAULT
;
362 if (IsEOL(sc
.ch
, sc
.chNext
)) {
365 if (sc
.ch
== chQuote
) {
366 sc
.ForwardSetState(endState
);
369 if (sc
.state
== SCE_T3_D_STRING
&& sc
.Match('<', '<')) {
370 lineState
|= T3_INT_EXPRESSION
;
371 sc
.SetState(SCE_T3_X_DEFAULT
);
375 if (sc
.Match('\\', static_cast<char>(chQuote
))) {
377 } else if (sc
.ch
== '{') {
378 ColouriseTADS3MsgParam(sc
, lineState
);
379 } else if (sc
.Match('<', '.')) {
380 ColouriseTADS3LibDirective(sc
, lineState
);
381 } else if (sc
.ch
== '<') {
382 ColouriseTADS3HTMLTag(sc
, lineState
);
389 static void ColouriseTADS3Comment(StyleContext
&sc
, int endState
) {
390 sc
.SetState(SCE_T3_BLOCK_COMMENT
);
392 if (IsEOL(sc
.ch
, sc
.chNext
)) {
395 if (sc
.Match('*', '/')) {
397 sc
.SetState(endState
);
404 static void ColouriseToEndOfLine(StyleContext
&sc
, int initState
, int endState
) {
405 sc
.SetState(initState
);
409 if (IsEOL(sc
.ch
, sc
.chNext
)) {
413 if (IsEOL(sc
.ch
, sc
.chNext
)) {
414 sc
.SetState(endState
);
421 static void ColouriseTADS3Number(StyleContext
&sc
) {
422 int endState
= sc
.state
;
423 bool inHexNumber
= false;
425 bool seenDot
= sc
.ch
== '.';
426 sc
.SetState(SCE_T3_NUMBER
);
430 if (sc
.chPrev
== '0' && tolower(sc
.ch
) == 'x') {
436 if (!IsAHexDigit(sc
.ch
)) {
439 } else if (!isdigit(sc
.ch
)) {
440 if (!seenE
&& tolower(sc
.ch
) == 'e') {
443 if (sc
.chNext
== '+' || sc
.chNext
== '-') {
446 } else if (!seenDot
&& sc
.ch
== '.') {
454 sc
.SetState(endState
);
457 static void ColouriseTADS3Doc(unsigned int startPos
, int length
, int initStyle
,
458 WordList
*keywordlists
[], Accessor
&styler
) {
459 int visibleChars
= 0;
460 int bracketLevel
= 0;
462 unsigned int endPos
= startPos
+ length
;
463 int lineCurrent
= styler
.GetLine(startPos
);
464 if (lineCurrent
> 0) {
465 lineState
= styler
.GetLineState(lineCurrent
-1);
467 StyleContext
sc(startPos
, length
, initStyle
, styler
);
471 if (IsEOL(sc
.ch
, sc
.chNext
)) {
472 styler
.SetLineState(lineCurrent
, lineState
);
482 case SCE_T3_PREPROCESSOR
:
483 case SCE_T3_LINE_COMMENT
:
484 ColouriseToEndOfLine(sc
, sc
.state
, lineState
&T3_INT_EXPRESSION
?
485 SCE_T3_X_DEFAULT
: SCE_T3_DEFAULT
);
487 case SCE_T3_S_STRING
:
488 case SCE_T3_D_STRING
:
489 case SCE_T3_X_STRING
:
490 ColouriseTADS3String(sc
, lineState
);
493 case SCE_T3_MSG_PARAM
:
494 ColouriseTADS3MsgParam(sc
, lineState
);
496 case SCE_T3_LIB_DIRECTIVE
:
497 ColouriseTADS3LibDirective(sc
, lineState
);
499 case SCE_T3_HTML_DEFAULT
:
500 ColouriseTADS3HTMLTag(sc
, lineState
);
502 case SCE_T3_HTML_STRING
:
503 ColouriseTADSHTMLString(sc
, lineState
);
505 case SCE_T3_BLOCK_COMMENT
:
506 ColouriseTADS3Comment(sc
, lineState
&T3_INT_EXPRESSION
?
507 SCE_T3_X_DEFAULT
: SCE_T3_DEFAULT
);
510 case SCE_T3_X_DEFAULT
:
511 if (IsASpaceOrTab(sc
.ch
)) {
513 } else if (sc
.ch
== '#' && visibleChars
== 0) {
514 ColouriseToEndOfLine(sc
, SCE_T3_PREPROCESSOR
, sc
.state
);
515 } else if (sc
.Match('/', '*')) {
516 ColouriseTADS3Comment(sc
, sc
.state
);
518 } else if (sc
.Match('/', '/')) {
519 ColouriseToEndOfLine(sc
, SCE_T3_LINE_COMMENT
, sc
.state
);
520 } else if (sc
.ch
== '"') {
522 ColouriseTADS3String(sc
, lineState
);
524 } else if (sc
.ch
== '\'') {
525 ColouriseTADS3String(sc
, lineState
);
527 } else if (sc
.state
== SCE_T3_X_DEFAULT
&& bracketLevel
== 0
528 && sc
.Match('>', '>')) {
530 sc
.SetState(SCE_T3_D_STRING
);
531 lineState
&= ~(T3_SINGLE_QUOTE
|T3_INT_EXPRESSION
);
532 } else if (IsATADS3Operator(sc
.ch
)) {
533 if (sc
.state
== SCE_T3_X_DEFAULT
) {
536 } else if (sc
.ch
== ')') {
540 ColouriseTADS3Operator(sc
);
542 } else if (IsANumberStart(sc
)) {
543 ColouriseTADS3Number(sc
);
545 } else if (IsAWordStart(sc
.ch
)) {
546 ColouriseTADS3Keyword(sc
, keywordlists
, endPos
);
548 } else if (sc
.Match("...")) {
549 sc
.SetState(SCE_T3_IDENTIFIER
);
551 sc
.SetState(SCE_T3_DEFAULT
);
558 sc
.SetState(SCE_T3_DEFAULT
);
566 TADS3 has two styles of top level block (TLB). Eg
569 silverKey : Key 'small silver key' 'small silver key'
570 "A small key glints in the sunlight. "
578 "A small key glints in the sunlight. "
581 Some constructs mandate one or the other, but usually the author has may choose
584 T3_SEENSTART is used to indicate that a braceless TLB has been (potentially)
585 seen and is also used to match the closing ';' of the default style.
587 T3_EXPECTINGIDENTIFIER and T3_EXPECTINGPUNCTUATION are used to keep track of
588 what characters may be seen without incrementing the block level. The general
589 pattern is identifier <punc> identifier, acceptable punctuation characters
590 are ':', ',', '(' and ')'. No attempt is made to ensure that punctuation
591 characters are syntactically correct, eg parentheses match. A ')' always
592 signifies the start of a block. We just need to check if it is followed by a
593 '{', in which case we let the brace handling code handle the folding level.
595 expectingIdentifier == false && expectingIdentifier == false
596 Before the start of a TLB.
598 expectingIdentifier == true && expectingIdentifier == true
599 Currently in an identifier. Will accept identifier or punctuation.
601 expectingIdentifier == true && expectingIdentifier == false
602 Just seen a punctuation character & now waiting for an identifier to start.
604 expectingIdentifier == false && expectingIdentifier == truee
605 We were in an identifier and have seen space. Now waiting to see a punctuation
608 Space, comments & preprocessor directives are always acceptable and are
612 static const int T3_SEENSTART
= 1 << 12;
613 static const int T3_EXPECTINGIDENTIFIER
= 1 << 13;
614 static const int T3_EXPECTINGPUNCTUATION
= 1 << 14;
616 static inline bool IsStringTransition(int s1
, int s2
) {
618 && (s1
== SCE_T3_S_STRING
|| s1
== SCE_T3_X_STRING
619 || s1
== SCE_T3_D_STRING
&& s2
!= SCE_T3_X_DEFAULT
)
620 && s2
!= SCE_T3_LIB_DIRECTIVE
621 && s2
!= SCE_T3_MSG_PARAM
622 && s2
!= SCE_T3_HTML_TAG
623 && s2
!= SCE_T3_HTML_STRING
;
626 static inline bool IsATADS3Punctuation(const int ch
) {
627 return ch
== ':' || ch
== ',' || ch
== '(' || ch
== ')';
630 static inline bool IsAnIdentifier(const int style
) {
631 return style
== SCE_T3_IDENTIFIER
632 || style
== SCE_T3_USER1
633 || style
== SCE_T3_USER2
634 || style
== SCE_T3_USER3
;
637 static inline bool IsSpaceEquivalent(const int ch
, const int style
) {
639 || style
== SCE_T3_BLOCK_COMMENT
640 || style
== SCE_T3_LINE_COMMENT
641 || style
== SCE_T3_PREPROCESSOR
;
644 static char peekAhead(unsigned int startPos
, unsigned int endPos
,
646 for (unsigned int i
= startPos
; i
< endPos
; i
++) {
647 int style
= styler
.StyleAt(i
);
649 if (!IsSpaceEquivalent(ch
, style
)) {
650 if (IsAnIdentifier(style
)) {
653 if (IsATADS3Punctuation(ch
)) {
665 static void FoldTADS3Doc(unsigned int startPos
, int length
, int initStyle
,
666 WordList
*[], Accessor
&styler
) {
667 unsigned int endPos
= startPos
+ length
;
668 int lineCurrent
= styler
.GetLine(startPos
);
669 int levelCurrent
= SC_FOLDLEVELBASE
;
671 levelCurrent
= styler
.LevelAt(lineCurrent
-1) >> 16;
672 int seenStart
= levelCurrent
& T3_SEENSTART
;
673 int expectingIdentifier
= levelCurrent
& T3_EXPECTINGIDENTIFIER
;
674 int expectingPunctuation
= levelCurrent
& T3_EXPECTINGPUNCTUATION
;
675 levelCurrent
&= SC_FOLDLEVELNUMBERMASK
;
676 int levelMinCurrent
= levelCurrent
;
677 int levelNext
= levelCurrent
;
678 char chNext
= styler
[startPos
];
679 int styleNext
= styler
.StyleAt(startPos
);
680 int style
= initStyle
;
682 int stylePrev
= style
;
684 for (unsigned int i
= startPos
; i
< endPos
; i
++) {
690 chNext
= styler
.SafeGetCharAt(i
+ 1);
693 styleNext
= styler
.StyleAt(i
+ 1);
695 bool atEOL
= IsEOL(ch
, chNext
);
697 if (levelNext
== SC_FOLDLEVELBASE
) {
698 if (IsSpaceEquivalent(ch
, style
)) {
699 if (expectingPunctuation
) {
700 expectingIdentifier
= 0;
702 if (style
== SCE_T3_BLOCK_COMMENT
) {
705 } else if (ch
== '{') {
708 } else if (ch
== '\'' || ch
== '"' || ch
== '[') {
713 } else if (ch
== ';') {
715 expectingIdentifier
= 0;
716 expectingPunctuation
= 0;
717 } else if (expectingIdentifier
&& expectingPunctuation
) {
718 if (IsATADS3Punctuation(ch
)) {
719 if (ch
== ')' && peekAhead(i
+1, endPos
, styler
) != '{') {
722 expectingPunctuation
= 0;
724 } else if (!IsAnIdentifier(style
)) {
727 } else if (expectingIdentifier
&& !expectingPunctuation
) {
728 if (!IsAnIdentifier(style
)) {
731 expectingPunctuation
= T3_EXPECTINGPUNCTUATION
;
733 } else if (!expectingIdentifier
&& expectingPunctuation
) {
734 if (!IsATADS3Punctuation(ch
)) {
737 if (ch
== ')' && peekAhead(i
+1, endPos
, styler
) != '{') {
740 expectingIdentifier
= T3_EXPECTINGIDENTIFIER
;
741 expectingPunctuation
= 0;
744 } else if (!expectingIdentifier
&& !expectingPunctuation
) {
745 if (IsAnIdentifier(style
)) {
746 seenStart
= T3_SEENSTART
;
747 expectingIdentifier
= T3_EXPECTINGIDENTIFIER
;
748 expectingPunctuation
= T3_EXPECTINGPUNCTUATION
;
752 if (levelNext
!= SC_FOLDLEVELBASE
&& style
!= SCE_T3_BLOCK_COMMENT
) {
753 expectingIdentifier
= 0;
754 expectingPunctuation
= 0;
757 } else if (levelNext
== SC_FOLDLEVELBASE
+1 && seenStart
758 && ch
== ';' && style
== SCE_T3_OPERATOR
) {
761 } else if (style
== SCE_T3_BLOCK_COMMENT
) {
762 if (stylePrev
!= SCE_T3_BLOCK_COMMENT
) {
764 } else if (styleNext
!= SCE_T3_BLOCK_COMMENT
&& !atEOL
) {
765 // Comments don't end at end of line and the next character may be unstyled.
768 } else if (ch
== '\'' || ch
== '"') {
769 if (IsStringTransition(style
, stylePrev
)) {
770 if (levelMinCurrent
> levelNext
) {
771 levelMinCurrent
= levelNext
;
774 } else if (IsStringTransition(style
, styleNext
)) {
777 } else if (style
== SCE_T3_OPERATOR
) {
778 if (ch
== '{' || ch
== '[') {
779 // Measure the minimum before a '{' to allow
780 // folding on "} else {"
781 if (levelMinCurrent
> levelNext
) {
782 levelMinCurrent
= levelNext
;
785 } else if (ch
== '}' || ch
== ']') {
791 if (seenStart
&& levelNext
== SC_FOLDLEVELBASE
) {
792 switch (peekAhead(i
+1, endPos
, styler
)) {
800 if (expectingPunctuation
) {
805 if (expectingIdentifier
) {
810 if (levelNext
!= SC_FOLDLEVELBASE
) {
811 expectingIdentifier
= 0;
812 expectingPunctuation
= 0;
815 int lev
= levelMinCurrent
| (levelNext
| expectingIdentifier
816 | expectingPunctuation
| seenStart
) << 16;
817 if (levelMinCurrent
< levelNext
)
818 lev
|= SC_FOLDLEVELHEADERFLAG
;
819 if (lev
!= styler
.LevelAt(lineCurrent
)) {
820 styler
.SetLevel(lineCurrent
, lev
);
823 levelCurrent
= levelNext
;
824 levelMinCurrent
= levelCurrent
;
829 static const char * const tads3WordList
[] = {
837 LexerModule
lmTADS3(SCLEX_TADS3
, ColouriseTADS3Doc
, "tads3", FoldTADS3Doc
, tads3WordList
);