aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/LexTADS3.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/LexTADS3.cxx')
-rw-r--r--src/LexTADS3.cxx904
1 files changed, 0 insertions, 904 deletions
diff --git a/src/LexTADS3.cxx b/src/LexTADS3.cxx
deleted file mode 100644
index ee16a0ac0..000000000
--- a/src/LexTADS3.cxx
+++ /dev/null
@@ -1,904 +0,0 @@
-// Scintilla source code edit control
-/** @file LexTADS3.cxx
- ** Lexer for TADS3.
- **/
-// Copyright 1998-2006 by Neil Hodgson <neilh@scintilla.org>
-// The License.txt file describes the conditions under which this software may be distributed.
-
-/*
- * TADS3 is a language designed by Michael J. Roberts for the writing of text
- * based games. TADS comes from Text Adventure Development System. It has good
- * support for the processing and outputting of formatted text and much of a
- * TADS program listing consists of strings.
- *
- * TADS has two types of strings, those enclosed in single quotes (') and those
- * enclosed in double quotes ("). These strings have different symantics and
- * can be given different highlighting if desired.
- *
- * There can be embedded within both types of strings html tags
- * ( <tag key=value> ), library directives ( <.directive> ), and message
- * parameters ( {The doctor's/his} ).
- *
- * Double quoted strings can also contain interpolated expressions
- * ( << rug.moved ? ' and a hole in the floor. ' : nil >> ). These expressions
- * may themselves contain single or double quoted strings, although the double
- * quoted strings may not contain interpolated expressions.
- *
- * These embedded constructs influence the output and formatting and are an
- * important part of a program and require highlighting.
- *
- * LINKS
- * http://www.tads.org/
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-static const int T3_SINGLE_QUOTE = 1;
-static const int T3_INT_EXPRESSION = 2;
-static const int T3_INT_EXPRESSION_IN_TAG = 4;
-static const int T3_HTML_SQUOTE = 8;
-
-static inline bool IsEOL(const int ch, const int chNext) {
- return (ch == '\r' && chNext != '\n') || (ch == '\n');
-}
-
-/*
- * Test the current character to see if it's the START of an EOL sequence;
- * if so, skip ahead to the last character of the sequence and return true,
- * and if not just return false. There are a few places where we want to
- * check to see if a newline sequence occurs at a particular point, but
- * where a caller expects a subroutine to stop only upon reaching the END
- * of a newline sequence (in particular, CR-LF on Windows). That's why
- * IsEOL() above only returns true on CR if the CR isn't followed by an LF
- * - it doesn't want to admit that there's a newline until reaching the END
- * of the sequence. We meet both needs by saying that there's a newline
- * when we see the CR in a CR-LF, but skipping the CR before returning so
- * that the caller's caller will see that we've stopped at the LF.
- */
-static inline bool IsEOLSkip(StyleContext &sc)
-{
- /* test for CR-LF */
- if (sc.ch == '\r' && sc.chNext == '\n')
- {
- /* got CR-LF - skip the CR and indicate that we're at a newline */
- sc.Forward();
- return true;
- }
-
- /*
- * in other cases, we have at most a 1-character newline, so do the
- * normal IsEOL test
- */
- return IsEOL(sc.ch, sc.chNext);
-}
-
-static inline bool IsASpaceOrTab(const int ch) {
- return ch == ' ' || ch == '\t';
-}
-
-static inline bool IsATADS3Operator(const int ch) {
- return ch == '=' || ch == '{' || ch == '}' || ch == '(' || ch == ')'
- || ch == '[' || ch == ']' || ch == ',' || ch == ':' || ch == ';'
- || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%'
- || ch == '?' || ch == '!' || ch == '<' || ch == '>' || ch == '|'
- || ch == '@' || ch == '&' || ch == '~';
-}
-
-static inline bool IsAWordChar(const int ch) {
- return isalnum(ch) || ch == '_';
-}
-
-static inline bool IsAWordStart(const int ch) {
- return isalpha(ch) || ch == '_';
-}
-
-static inline bool IsAHexDigit(const int ch) {
- int lch = tolower(ch);
- return isdigit(lch) || lch == 'a' || lch == 'b' || lch == 'c'
- || lch == 'd' || lch == 'e' || lch == 'f';
-}
-
-static inline bool IsAnHTMLChar(int ch) {
- return isalnum(ch) || ch == '-' || ch == '_' || ch == '.';
-}
-
-static inline bool IsADirectiveChar(int ch) {
- return isalnum(ch) || isspace(ch) || ch == '-' || ch == '/';
-}
-
-static inline bool IsANumberStart(StyleContext &sc) {
- return isdigit(sc.ch)
- || (!isdigit(sc.chPrev) && sc.ch == '.' && isdigit(sc.chNext));
-}
-
-inline static void ColouriseTADS3Operator(StyleContext &sc) {
- int initState = sc.state;
- int c = sc.ch;
- sc.SetState(c == '{' || c == '}' ? SCE_T3_BRACE : SCE_T3_OPERATOR);
- sc.ForwardSetState(initState);
-}
-
-static void ColouriseTADSHTMLString(StyleContext &sc, int &lineState) {
- int endState = sc.state;
- int chQuote = sc.ch;
- int chString = (lineState & T3_SINGLE_QUOTE) ? '\'' : '"';
- if (endState == SCE_T3_HTML_STRING) {
- if (lineState&T3_SINGLE_QUOTE) {
- endState = SCE_T3_S_STRING;
- chString = '\'';
- } else if (lineState&T3_INT_EXPRESSION) {
- endState = SCE_T3_X_STRING;
- chString = '"';
- } else {
- endState = SCE_T3_HTML_DEFAULT;
- chString = '"';
- }
- chQuote = (lineState & T3_HTML_SQUOTE) ? '\'' : '"';
- } else {
- sc.SetState(SCE_T3_HTML_STRING);
- sc.Forward();
- }
- if (chQuote == '"')
- lineState &= ~T3_HTML_SQUOTE;
- else
- lineState |= T3_HTML_SQUOTE;
-
- while (sc.More()) {
- if (IsEOL(sc.ch, sc.chNext)) {
- return;
- }
- if (sc.ch == chQuote) {
- sc.ForwardSetState(endState);
- return;
- }
- if (sc.Match('\\', static_cast<char>(chQuote))) {
- sc.Forward(2);
- sc.SetState(endState);
- return;
- }
- if (sc.ch == chString) {
- sc.SetState(SCE_T3_DEFAULT);
- return;
- }
-
- if (sc.Match('<', '<')) {
- lineState |= T3_INT_EXPRESSION | T3_INT_EXPRESSION_IN_TAG;
- sc.SetState(SCE_T3_X_DEFAULT);
- sc.Forward(2);
- return;
- }
-
- if (sc.Match('\\', static_cast<char>(chQuote))
- || sc.Match('\\', static_cast<char>(chString))
- || sc.Match('\\', '\\')) {
- sc.Forward(2);
- } else {
- sc.Forward();
- }
- }
-}
-
-static void ColouriseTADS3HTMLTagStart(StyleContext &sc) {
- sc.SetState(SCE_T3_HTML_TAG);
- sc.Forward();
- if (sc.ch == '/') {
- sc.Forward();
- }
- while (IsAnHTMLChar(sc.ch)) {
- sc.Forward();
- }
-}
-
-static void ColouriseTADS3HTMLTag(StyleContext &sc, int &lineState) {
- int endState = sc.state;
- int chQuote = '"';
- int chString = '\'';
- switch (endState) {
- case SCE_T3_S_STRING:
- ColouriseTADS3HTMLTagStart(sc);
- sc.SetState(SCE_T3_HTML_DEFAULT);
- chQuote = '\'';
- chString = '"';
- break;
- case SCE_T3_D_STRING:
- case SCE_T3_X_STRING:
- ColouriseTADS3HTMLTagStart(sc);
- sc.SetState(SCE_T3_HTML_DEFAULT);
- break;
- case SCE_T3_HTML_DEFAULT:
- if (lineState&T3_SINGLE_QUOTE) {
- endState = SCE_T3_S_STRING;
- chQuote = '\'';
- chString = '"';
- } else if (lineState&T3_INT_EXPRESSION) {
- endState = SCE_T3_X_STRING;
- } else {
- endState = SCE_T3_D_STRING;
- }
- break;
- }
-
- while (sc.More()) {
- if (IsEOL(sc.ch, sc.chNext)) {
- return;
- }
- if (sc.Match('/', '>')) {
- sc.SetState(SCE_T3_HTML_TAG);
- sc.Forward(2);
- sc.SetState(endState);
- return;
- }
- if (sc.ch == '>') {
- sc.SetState(SCE_T3_HTML_TAG);
- sc.ForwardSetState(endState);
- return;
- }
- if (sc.ch == chQuote) {
- sc.SetState(endState);
- return;
- }
- if (sc.Match('\\', static_cast<char>(chQuote))) {
- sc.Forward();
- ColouriseTADSHTMLString(sc, lineState);
- if (sc.state == SCE_T3_X_DEFAULT)
- break;
- } else if (sc.ch == chString) {
- ColouriseTADSHTMLString(sc, lineState);
- } else if (sc.ch == '=') {
- ColouriseTADS3Operator(sc);
- } else {
- sc.Forward();
- }
- }
-}
-
-static void ColouriseTADS3Keyword(StyleContext &sc,
- WordList *keywordlists[], unsigned int endPos) {
- char s[250];
- WordList &keywords = *keywordlists[0];
- WordList &userwords1 = *keywordlists[1];
- WordList &userwords2 = *keywordlists[2];
- WordList &userwords3 = *keywordlists[3];
- int initState = sc.state;
- sc.SetState(SCE_T3_IDENTIFIER);
- while (sc.More() && (IsAWordChar(sc.ch))) {
- sc.Forward();
- }
- sc.GetCurrent(s, sizeof(s));
- if ( strcmp(s, "is") == 0 || strcmp(s, "not") == 0) {
- // have to find if "in" is next
- int n = 1;
- while (n + sc.currentPos < endPos && IsASpaceOrTab(sc.GetRelative(n)))
- n++;
- if (sc.GetRelative(n) == 'i' && sc.GetRelative(n+1) == 'n') {
- sc.Forward(n+2);
- sc.ChangeState(SCE_T3_KEYWORD);
- }
- } else if (keywords.InList(s)) {
- sc.ChangeState(SCE_T3_KEYWORD);
- } else if (userwords3.InList(s)) {
- sc.ChangeState(SCE_T3_USER3);
- } else if (userwords2.InList(s)) {
- sc.ChangeState(SCE_T3_USER2);
- } else if (userwords1.InList(s)) {
- sc.ChangeState(SCE_T3_USER1);
- }
- sc.SetState(initState);
-}
-
-static void ColouriseTADS3MsgParam(StyleContext &sc, int &lineState) {
- int endState = sc.state;
- int chQuote = '"';
- switch (endState) {
- case SCE_T3_S_STRING:
- sc.SetState(SCE_T3_MSG_PARAM);
- sc.Forward();
- chQuote = '\'';
- break;
- case SCE_T3_D_STRING:
- case SCE_T3_X_STRING:
- sc.SetState(SCE_T3_MSG_PARAM);
- sc.Forward();
- break;
- case SCE_T3_MSG_PARAM:
- if (lineState&T3_SINGLE_QUOTE) {
- endState = SCE_T3_S_STRING;
- chQuote = '\'';
- } else if (lineState&T3_INT_EXPRESSION) {
- endState = SCE_T3_X_STRING;
- } else {
- endState = SCE_T3_D_STRING;
- }
- break;
- }
- while (sc.More() && sc.ch != '}' && sc.ch != chQuote) {
- if (IsEOL(sc.ch, sc.chNext)) {
- return;
- }
- if (sc.ch == '\\') {
- sc.Forward();
- }
- sc.Forward();
- }
- if (sc.ch == chQuote) {
- sc.SetState(endState);
- } else {
- sc.ForwardSetState(endState);
- }
-}
-
-static void ColouriseTADS3LibDirective(StyleContext &sc, int &lineState) {
- int initState = sc.state;
- int chQuote = '"';
- switch (initState) {
- case SCE_T3_S_STRING:
- sc.SetState(SCE_T3_LIB_DIRECTIVE);
- sc.Forward(2);
- chQuote = '\'';
- break;
- case SCE_T3_D_STRING:
- sc.SetState(SCE_T3_LIB_DIRECTIVE);
- sc.Forward(2);
- break;
- case SCE_T3_LIB_DIRECTIVE:
- if (lineState&T3_SINGLE_QUOTE) {
- initState = SCE_T3_S_STRING;
- chQuote = '\'';
- } else {
- initState = SCE_T3_D_STRING;
- }
- break;
- }
- while (sc.More() && IsADirectiveChar(sc.ch)) {
- if (IsEOL(sc.ch, sc.chNext)) {
- return;
- }
- sc.Forward();
- };
- if (sc.ch == '>' || !sc.More()) {
- sc.ForwardSetState(initState);
- } else if (sc.ch == chQuote) {
- sc.SetState(initState);
- } else {
- sc.ChangeState(initState);
- sc.Forward();
- }
-}
-
-static void ColouriseTADS3String(StyleContext &sc, int &lineState) {
- int chQuote = sc.ch;
- int endState = sc.state;
- switch (sc.state) {
- case SCE_T3_DEFAULT:
- case SCE_T3_X_DEFAULT:
- if (chQuote == '"') {
- if (sc.state == SCE_T3_DEFAULT) {
- sc.SetState(SCE_T3_D_STRING);
- } else {
- sc.SetState(SCE_T3_X_STRING);
- }
- lineState &= ~T3_SINGLE_QUOTE;
- } else {
- sc.SetState(SCE_T3_S_STRING);
- lineState |= T3_SINGLE_QUOTE;
- }
- sc.Forward();
- break;
- case SCE_T3_S_STRING:
- chQuote = '\'';
- endState = lineState&T3_INT_EXPRESSION ?
- SCE_T3_X_DEFAULT : SCE_T3_DEFAULT;
- break;
- case SCE_T3_D_STRING:
- chQuote = '"';
- endState = SCE_T3_DEFAULT;
- break;
- case SCE_T3_X_STRING:
- chQuote = '"';
- endState = SCE_T3_X_DEFAULT;
- break;
- }
- while (sc.More()) {
- if (IsEOL(sc.ch, sc.chNext)) {
- return;
- }
- if (sc.ch == chQuote) {
- sc.ForwardSetState(endState);
- return;
- }
- if (sc.state == SCE_T3_D_STRING && sc.Match('<', '<')) {
- lineState |= T3_INT_EXPRESSION;
- sc.SetState(SCE_T3_X_DEFAULT);
- sc.Forward(2);
- return;
- }
- if (sc.Match('\\', static_cast<char>(chQuote))
- || sc.Match('\\', '\\')) {
- sc.Forward(2);
- } else if (sc.ch == '{') {
- ColouriseTADS3MsgParam(sc, lineState);
- } else if (sc.Match('<', '.')) {
- ColouriseTADS3LibDirective(sc, lineState);
- } else if (sc.ch == '<') {
- ColouriseTADS3HTMLTag(sc, lineState);
- if (sc.state == SCE_T3_X_DEFAULT)
- return;
- } else {
- sc.Forward();
- }
- }
-}
-
-static void ColouriseTADS3Comment(StyleContext &sc, int endState) {
- sc.SetState(SCE_T3_BLOCK_COMMENT);
- while (sc.More()) {
- if (IsEOL(sc.ch, sc.chNext)) {
- return;
- }
- if (sc.Match('*', '/')) {
- sc.Forward(2);
- sc.SetState(endState);
- return;
- }
- sc.Forward();
- }
-}
-
-static void ColouriseToEndOfLine(StyleContext &sc, int initState, int endState) {
- sc.SetState(initState);
- while (sc.More()) {
- if (sc.ch == '\\') {
- sc.Forward();
- if (IsEOLSkip(sc)) {
- return;
- }
- }
- if (IsEOL(sc.ch, sc.chNext)) {
- sc.SetState(endState);
- return;
- }
- sc.Forward();
- }
-}
-
-static void ColouriseTADS3Number(StyleContext &sc) {
- int endState = sc.state;
- bool inHexNumber = false;
- bool seenE = false;
- bool seenDot = sc.ch == '.';
- sc.SetState(SCE_T3_NUMBER);
- if (sc.More()) {
- sc.Forward();
- }
- if (sc.chPrev == '0' && tolower(sc.ch) == 'x') {
- inHexNumber = true;
- sc.Forward();
- }
- while (sc.More()) {
- if (inHexNumber) {
- if (!IsAHexDigit(sc.ch)) {
- break;
- }
- } else if (!isdigit(sc.ch)) {
- if (!seenE && tolower(sc.ch) == 'e') {
- seenE = true;
- seenDot = true;
- if (sc.chNext == '+' || sc.chNext == '-') {
- sc.Forward();
- }
- } else if (!seenDot && sc.ch == '.') {
- seenDot = true;
- } else {
- break;
- }
- }
- sc.Forward();
- }
- sc.SetState(endState);
-}
-
-static void ColouriseTADS3Doc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- int visibleChars = 0;
- int bracketLevel = 0;
- int lineState = 0;
- unsigned int endPos = startPos + length;
- int lineCurrent = styler.GetLine(startPos);
- if (lineCurrent > 0) {
- lineState = styler.GetLineState(lineCurrent-1);
- }
- StyleContext sc(startPos, length, initStyle, styler);
-
- while (sc.More()) {
-
- if (IsEOL(sc.ch, sc.chNext)) {
- styler.SetLineState(lineCurrent, lineState);
- lineCurrent++;
- visibleChars = 0;
- sc.Forward();
- if (sc.ch == '\n') {
- sc.Forward();
- }
- }
-
- switch(sc.state) {
- case SCE_T3_PREPROCESSOR:
- case SCE_T3_LINE_COMMENT:
- ColouriseToEndOfLine(sc, sc.state, lineState&T3_INT_EXPRESSION ?
- SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
- break;
- case SCE_T3_S_STRING:
- case SCE_T3_D_STRING:
- case SCE_T3_X_STRING:
- ColouriseTADS3String(sc, lineState);
- visibleChars++;
- break;
- case SCE_T3_MSG_PARAM:
- ColouriseTADS3MsgParam(sc, lineState);
- break;
- case SCE_T3_LIB_DIRECTIVE:
- ColouriseTADS3LibDirective(sc, lineState);
- break;
- case SCE_T3_HTML_DEFAULT:
- ColouriseTADS3HTMLTag(sc, lineState);
- break;
- case SCE_T3_HTML_STRING:
- ColouriseTADSHTMLString(sc, lineState);
- break;
- case SCE_T3_BLOCK_COMMENT:
- ColouriseTADS3Comment(sc, lineState&T3_INT_EXPRESSION ?
- SCE_T3_X_DEFAULT : SCE_T3_DEFAULT);
- break;
- case SCE_T3_DEFAULT:
- case SCE_T3_X_DEFAULT:
- if (IsASpaceOrTab(sc.ch)) {
- sc.Forward();
- } else if (sc.ch == '#' && visibleChars == 0) {
- ColouriseToEndOfLine(sc, SCE_T3_PREPROCESSOR, sc.state);
- } else if (sc.Match('/', '*')) {
- ColouriseTADS3Comment(sc, sc.state);
- visibleChars++;
- } else if (sc.Match('/', '/')) {
- ColouriseToEndOfLine(sc, SCE_T3_LINE_COMMENT, sc.state);
- } else if (sc.ch == '"') {
- bracketLevel = 0;
- ColouriseTADS3String(sc, lineState);
- visibleChars++;
- } else if (sc.ch == '\'') {
- ColouriseTADS3String(sc, lineState);
- visibleChars++;
- } else if (sc.state == SCE_T3_X_DEFAULT && bracketLevel == 0
- && sc.Match('>', '>')) {
- sc.Forward(2);
- sc.SetState(SCE_T3_D_STRING);
- if (lineState & T3_INT_EXPRESSION_IN_TAG)
- sc.SetState(SCE_T3_HTML_STRING);
- lineState &= ~(T3_SINGLE_QUOTE|T3_INT_EXPRESSION
- |T3_INT_EXPRESSION_IN_TAG);
- } else if (IsATADS3Operator(sc.ch)) {
- if (sc.state == SCE_T3_X_DEFAULT) {
- if (sc.ch == '(') {
- bracketLevel++;
- } else if (sc.ch == ')' && bracketLevel > 0) {
- bracketLevel--;
- }
- }
- ColouriseTADS3Operator(sc);
- visibleChars++;
- } else if (IsANumberStart(sc)) {
- ColouriseTADS3Number(sc);
- visibleChars++;
- } else if (IsAWordStart(sc.ch)) {
- ColouriseTADS3Keyword(sc, keywordlists, endPos);
- visibleChars++;
- } else if (sc.Match("...")) {
- sc.SetState(SCE_T3_IDENTIFIER);
- sc.Forward(3);
- sc.SetState(SCE_T3_DEFAULT);
- } else {
- sc.Forward();
- visibleChars++;
- }
- break;
- default:
- sc.SetState(SCE_T3_DEFAULT);
- sc.Forward();
- }
- }
- sc.Complete();
-}
-
-/*
- TADS3 has two styles of top level block (TLB). Eg
-
- // default style
- silverKey : Key 'small silver key' 'small silver key'
- "A small key glints in the sunlight. "
- ;
-
- and
-
- silverKey : Key {
- 'small silver key'
- 'small silver key'
- "A small key glints in the sunlight. "
- }
-
- Some constructs mandate one or the other, but usually the author has may choose
- either.
-
- T3_SEENSTART is used to indicate that a braceless TLB has been (potentially)
- seen and is also used to match the closing ';' of the default style.
-
- T3_EXPECTINGIDENTIFIER and T3_EXPECTINGPUNCTUATION are used to keep track of
- what characters may be seen without incrementing the block level. The general
- pattern is identifier <punc> identifier, acceptable punctuation characters
- are ':', ',', '(' and ')'. No attempt is made to ensure that punctuation
- characters are syntactically correct, eg parentheses match. A ')' always
- signifies the start of a block. We just need to check if it is followed by a
- '{', in which case we let the brace handling code handle the folding level.
-
- expectingIdentifier == false && expectingIdentifier == false
- Before the start of a TLB.
-
- expectingIdentifier == true && expectingIdentifier == true
- Currently in an identifier. Will accept identifier or punctuation.
-
- expectingIdentifier == true && expectingIdentifier == false
- Just seen a punctuation character & now waiting for an identifier to start.
-
- expectingIdentifier == false && expectingIdentifier == truee
- We were in an identifier and have seen space. Now waiting to see a punctuation
- character
-
- Space, comments & preprocessor directives are always acceptable and are
- equivalent.
-*/
-
-static const int T3_SEENSTART = 1 << 12;
-static const int T3_EXPECTINGIDENTIFIER = 1 << 13;
-static const int T3_EXPECTINGPUNCTUATION = 1 << 14;
-
-static inline bool IsStringTransition(int s1, int s2) {
- return s1 != s2
- && (s1 == SCE_T3_S_STRING || s1 == SCE_T3_X_STRING
- || (s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT))
- && s2 != SCE_T3_LIB_DIRECTIVE
- && s2 != SCE_T3_MSG_PARAM
- && s2 != SCE_T3_HTML_TAG
- && s2 != SCE_T3_HTML_STRING;
-}
-
-static inline bool IsATADS3Punctuation(const int ch) {
- return ch == ':' || ch == ',' || ch == '(' || ch == ')';
-}
-
-static inline bool IsAnIdentifier(const int style) {
- return style == SCE_T3_IDENTIFIER
- || style == SCE_T3_USER1
- || style == SCE_T3_USER2
- || style == SCE_T3_USER3;
-}
-
-static inline bool IsAnOperator(const int style) {
- return style == SCE_T3_OPERATOR || SCE_T3_BRACE;
-}
-
-static inline bool IsSpaceEquivalent(const int ch, const int style) {
- return isspace(ch)
- || style == SCE_T3_BLOCK_COMMENT
- || style == SCE_T3_LINE_COMMENT
- || style == SCE_T3_PREPROCESSOR;
-}
-
-static char peekAhead(unsigned int startPos, unsigned int endPos,
- Accessor &styler) {
- for (unsigned int i = startPos; i < endPos; i++) {
- int style = styler.StyleAt(i);
- char ch = styler[i];
- if (!IsSpaceEquivalent(ch, style)) {
- if (IsAnIdentifier(style)) {
- return 'a';
- }
- if (IsATADS3Punctuation(ch)) {
- return ':';
- }
- if (ch == '{') {
- return '{';
- }
- return '*';
- }
- }
- return ' ';
-}
-
-static void FoldTADS3Doc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- unsigned int endPos = startPos + length;
- int lineCurrent = styler.GetLine(startPos);
- int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- int seenStart = levelCurrent & T3_SEENSTART;
- int expectingIdentifier = levelCurrent & T3_EXPECTINGIDENTIFIER;
- int expectingPunctuation = levelCurrent & T3_EXPECTINGPUNCTUATION;
- levelCurrent &= SC_FOLDLEVELNUMBERMASK;
- int levelMinCurrent = levelCurrent;
- int levelNext = levelCurrent;
- char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
- char ch = chNext;
- int stylePrev = style;
- bool redo = false;
- for (unsigned int i = startPos; i < endPos; i++) {
- if (redo) {
- redo = false;
- i--;
- } else {
- ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- stylePrev = style;
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- }
- bool atEOL = IsEOL(ch, chNext);
-
- if (levelNext == SC_FOLDLEVELBASE) {
- if (IsSpaceEquivalent(ch, style)) {
- if (expectingPunctuation) {
- expectingIdentifier = 0;
- }
- if (style == SCE_T3_BLOCK_COMMENT) {
- levelNext++;
- }
- } else if (ch == '{') {
- levelNext++;
- seenStart = 0;
- } else if (ch == '\'' || ch == '"' || ch == '[') {
- levelNext++;
- if (seenStart) {
- redo = true;
- }
- } else if (ch == ';') {
- seenStart = 0;
- expectingIdentifier = 0;
- expectingPunctuation = 0;
- } else if (expectingIdentifier && expectingPunctuation) {
- if (IsATADS3Punctuation(ch)) {
- if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {
- levelNext++;
- } else {
- expectingPunctuation = 0;
- }
- } else if (!IsAnIdentifier(style)) {
- levelNext++;
- }
- } else if (expectingIdentifier && !expectingPunctuation) {
- if (!IsAnIdentifier(style)) {
- levelNext++;
- } else {
- expectingPunctuation = T3_EXPECTINGPUNCTUATION;
- }
- } else if (!expectingIdentifier && expectingPunctuation) {
- if (!IsATADS3Punctuation(ch)) {
- levelNext++;
- } else {
- if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') {
- levelNext++;
- } else {
- expectingIdentifier = T3_EXPECTINGIDENTIFIER;
- expectingPunctuation = 0;
- }
- }
- } else if (!expectingIdentifier && !expectingPunctuation) {
- if (IsAnIdentifier(style)) {
- seenStart = T3_SEENSTART;
- expectingIdentifier = T3_EXPECTINGIDENTIFIER;
- expectingPunctuation = T3_EXPECTINGPUNCTUATION;
- }
- }
-
- if (levelNext != SC_FOLDLEVELBASE && style != SCE_T3_BLOCK_COMMENT) {
- expectingIdentifier = 0;
- expectingPunctuation = 0;
- }
-
- } else if (levelNext == SC_FOLDLEVELBASE+1 && seenStart
- && ch == ';' && IsAnOperator(style)) {
- levelNext--;
- seenStart = 0;
- } else if (style == SCE_T3_BLOCK_COMMENT) {
- if (stylePrev != SCE_T3_BLOCK_COMMENT) {
- levelNext++;
- } else if (styleNext != SCE_T3_BLOCK_COMMENT && !atEOL) {
- // Comments don't end at end of line and the next character may be unstyled.
- levelNext--;
- }
- } else if (ch == '\'' || ch == '"') {
- if (IsStringTransition(style, stylePrev)) {
- if (levelMinCurrent > levelNext) {
- levelMinCurrent = levelNext;
- }
- levelNext++;
- } else if (IsStringTransition(style, styleNext)) {
- levelNext--;
- }
- } else if (IsAnOperator(style)) {
- if (ch == '{' || ch == '[') {
- // Measure the minimum before a '{' to allow
- // folding on "} else {"
- if (levelMinCurrent > levelNext) {
- levelMinCurrent = levelNext;
- }
- levelNext++;
- } else if (ch == '}' || ch == ']') {
- levelNext--;
- }
- }
-
- if (atEOL) {
- if (seenStart && levelNext == SC_FOLDLEVELBASE) {
- switch (peekAhead(i+1, endPos, styler)) {
- case ' ':
- case '{':
- break;
- case '*':
- levelNext++;
- break;
- case 'a':
- if (expectingPunctuation) {
- levelNext++;
- }
- break;
- case ':':
- if (expectingIdentifier) {
- levelNext++;
- }
- break;
- }
- if (levelNext != SC_FOLDLEVELBASE) {
- expectingIdentifier = 0;
- expectingPunctuation = 0;
- }
- }
- int lev = levelMinCurrent | (levelNext | expectingIdentifier
- | expectingPunctuation | seenStart) << 16;
- if (levelMinCurrent < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelCurrent = levelNext;
- levelMinCurrent = levelCurrent;
- }
- }
-}
-
-static const char * const tads3WordList[] = {
- "TADS3 Keywords",
- "User defined 1",
- "User defined 2",
- "User defined 3",
- 0
-};
-
-LexerModule lmTADS3(SCLEX_TADS3, ColouriseTADS3Doc, "tads3", FoldTADS3Doc, tads3WordList);