summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/3rdparty/scintilla/lexers/LexHaskell.cxx
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/3rdparty/scintilla/lexers/LexHaskell.cxx')
-rw-r--r--3rdparty/bgfx/3rdparty/scintilla/lexers/LexHaskell.cxx1111
1 files changed, 0 insertions, 1111 deletions
diff --git a/3rdparty/bgfx/3rdparty/scintilla/lexers/LexHaskell.cxx b/3rdparty/bgfx/3rdparty/scintilla/lexers/LexHaskell.cxx
deleted file mode 100644
index 24355fa4e44..00000000000
--- a/3rdparty/bgfx/3rdparty/scintilla/lexers/LexHaskell.cxx
+++ /dev/null
@@ -1,1111 +0,0 @@
-/******************************************************************
- * LexHaskell.cxx
- *
- * A haskell lexer for the scintilla code control.
- * Some stuff "lended" from LexPython.cxx and LexCPP.cxx.
- * External lexer stuff inspired from the caml external lexer.
- * Folder copied from Python's.
- *
- * Written by Tobias Engvall - tumm at dtek dot chalmers dot se
- *
- * Several bug fixes by Krasimir Angelov - kr.angelov at gmail.com
- *
- * Improved by kudah <kudahkukarek@gmail.com>
- *
- * TODO:
- * * A proper lexical folder to fold group declarations, comments, pragmas,
- * #ifdefs, explicit layout, lists, tuples, quasi-quotes, splces, etc, etc,
- * etc.
- *
- *****************************************************************/
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <ctype.h>
-
-#include <string>
-#include <map>
-
-#include "ILexer.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
-
-#include "PropSetSimple.h"
-#include "WordList.h"
-#include "LexAccessor.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "CharacterSet.h"
-#include "CharacterCategory.h"
-#include "LexerModule.h"
-#include "OptionSet.h"
-
-#ifdef SCI_NAMESPACE
-using namespace Scintilla;
-#endif
-
-// See https://github.com/ghc/ghc/blob/master/compiler/parser/Lexer.x#L1682
-// Note, letter modifiers are prohibited.
-
-static int u_iswupper (int ch) {
- CharacterCategory c = CategoriseCharacter(ch);
- return c == ccLu || c == ccLt;
-}
-
-static int u_iswalpha (int ch) {
- CharacterCategory c = CategoriseCharacter(ch);
- return c == ccLl || c == ccLu || c == ccLt || c == ccLo;
-}
-
-static int u_iswalnum (int ch) {
- CharacterCategory c = CategoriseCharacter(ch);
- return c == ccLl || c == ccLu || c == ccLt || c == ccLo
- || c == ccNd || c == ccNo;
-}
-
-static int u_IsHaskellSymbol(int ch) {
- CharacterCategory c = CategoriseCharacter(ch);
- return c == ccPc || c == ccPd || c == ccPo
- || c == ccSm || c == ccSc || c == ccSk || c == ccSo;
-}
-
-static inline bool IsHaskellLetter(const int ch) {
- if (IsASCII(ch)) {
- return (ch >= 'a' && ch <= 'z')
- || (ch >= 'A' && ch <= 'Z');
- } else {
- return u_iswalpha(ch) != 0;
- }
-}
-
-static inline bool IsHaskellAlphaNumeric(const int ch) {
- if (IsASCII(ch)) {
- return IsAlphaNumeric(ch);
- } else {
- return u_iswalnum(ch) != 0;
- }
-}
-
-static inline bool IsHaskellUpperCase(const int ch) {
- if (IsASCII(ch)) {
- return ch >= 'A' && ch <= 'Z';
- } else {
- return u_iswupper(ch) != 0;
- }
-}
-
-static inline bool IsAnHaskellOperatorChar(const int ch) {
- if (IsASCII(ch)) {
- return
- ( ch == '!' || ch == '#' || ch == '$' || ch == '%'
- || ch == '&' || ch == '*' || ch == '+' || ch == '-'
- || ch == '.' || ch == '/' || ch == ':' || ch == '<'
- || ch == '=' || ch == '>' || ch == '?' || ch == '@'
- || ch == '^' || ch == '|' || ch == '~' || ch == '\\');
- } else {
- return u_IsHaskellSymbol(ch) != 0;
- }
-}
-
-static inline bool IsAHaskellWordStart(const int ch) {
- return IsHaskellLetter(ch) || ch == '_';
-}
-
-static inline bool IsAHaskellWordChar(const int ch) {
- return ( IsHaskellAlphaNumeric(ch)
- || ch == '_'
- || ch == '\'');
-}
-
-static inline bool IsCommentBlockStyle(int style) {
- return (style >= SCE_HA_COMMENTBLOCK && style <= SCE_HA_COMMENTBLOCK3);
-}
-
-static inline bool IsCommentStyle(int style) {
- return (style >= SCE_HA_COMMENTLINE && style <= SCE_HA_COMMENTBLOCK3)
- || ( style == SCE_HA_LITERATE_COMMENT
- || style == SCE_HA_LITERATE_CODEDELIM);
-}
-
-// styles which do not belong to Haskell, but to external tools
-static inline bool IsExternalStyle(int style) {
- return ( style == SCE_HA_PREPROCESSOR
- || style == SCE_HA_LITERATE_COMMENT
- || style == SCE_HA_LITERATE_CODEDELIM);
-}
-
-static inline int CommentBlockStyleFromNestLevel(const unsigned int nestLevel) {
- return SCE_HA_COMMENTBLOCK + (nestLevel % 3);
-}
-
-// Mangled version of lexlib/Accessor.cxx IndentAmount.
-// Modified to treat comment blocks as whitespace
-// plus special case for commentline/preprocessor.
-static int HaskellIndentAmount(Accessor &styler, const int line) {
-
- // Determines the indentation level of the current line
- // Comment blocks are treated as whitespace
-
- int pos = styler.LineStart(line);
- int eol_pos = styler.LineStart(line + 1) - 1;
-
- char ch = styler[pos];
- int style = styler.StyleAt(pos);
-
- int indent = 0;
- bool inPrevPrefix = line > 0;
-
- int posPrev = inPrevPrefix ? styler.LineStart(line-1) : 0;
-
- while (( ch == ' ' || ch == '\t'
- || IsCommentBlockStyle(style)
- || style == SCE_HA_LITERATE_CODEDELIM)
- && (pos < eol_pos)) {
- if (inPrevPrefix) {
- char chPrev = styler[posPrev++];
- if (chPrev != ' ' && chPrev != '\t') {
- inPrevPrefix = false;
- }
- }
- if (ch == '\t') {
- indent = (indent / 8 + 1) * 8;
- } else { // Space or comment block
- indent++;
- }
- pos++;
- ch = styler[pos];
- style = styler.StyleAt(pos);
- }
-
- indent += SC_FOLDLEVELBASE;
- // if completely empty line or the start of a comment or preprocessor...
- if ( styler.LineStart(line) == styler.Length()
- || ch == ' '
- || ch == '\t'
- || ch == '\n'
- || ch == '\r'
- || IsCommentStyle(style)
- || style == SCE_HA_PREPROCESSOR)
- return indent | SC_FOLDLEVELWHITEFLAG;
- else
- return indent;
-}
-
-struct OptionsHaskell {
- bool magicHash;
- bool allowQuotes;
- bool implicitParams;
- bool highlightSafe;
- bool cpp;
- bool stylingWithinPreprocessor;
- bool fold;
- bool foldComment;
- bool foldCompact;
- bool foldImports;
- OptionsHaskell() {
- magicHash = true; // Widespread use, enabled by default.
- allowQuotes = true; // Widespread use, enabled by default.
- implicitParams = false; // Fell out of favor, seldom used, disabled.
- highlightSafe = true; // Moderately used, doesn't hurt to enable.
- cpp = true; // Widespread use, enabled by default;
- stylingWithinPreprocessor = false;
- fold = false;
- foldComment = false;
- foldCompact = false;
- foldImports = false;
- }
-};
-
-static const char * const haskellWordListDesc[] = {
- "Keywords",
- "FFI",
- "Reserved operators",
- 0
-};
-
-struct OptionSetHaskell : public OptionSet<OptionsHaskell> {
- OptionSetHaskell() {
- DefineProperty("lexer.haskell.allow.hash", &OptionsHaskell::magicHash,
- "Set to 0 to disallow the '#' character at the end of identifiers and "
- "literals with the haskell lexer "
- "(GHC -XMagicHash extension)");
-
- DefineProperty("lexer.haskell.allow.quotes", &OptionsHaskell::allowQuotes,
- "Set to 0 to disable highlighting of Template Haskell name quotations "
- "and promoted constructors "
- "(GHC -XTemplateHaskell and -XDataKinds extensions)");
-
- DefineProperty("lexer.haskell.allow.questionmark", &OptionsHaskell::implicitParams,
- "Set to 1 to allow the '?' character at the start of identifiers "
- "with the haskell lexer "
- "(GHC & Hugs -XImplicitParams extension)");
-
- DefineProperty("lexer.haskell.import.safe", &OptionsHaskell::highlightSafe,
- "Set to 0 to disallow \"safe\" keyword in imports "
- "(GHC -XSafe, -XTrustworthy, -XUnsafe extensions)");
-
- DefineProperty("lexer.haskell.cpp", &OptionsHaskell::cpp,
- "Set to 0 to disable C-preprocessor highlighting "
- "(-XCPP extension)");
-
- DefineProperty("styling.within.preprocessor", &OptionsHaskell::stylingWithinPreprocessor,
- "For Haskell code, determines whether all preprocessor code is styled in the "
- "preprocessor style (0, the default) or only from the initial # to the end "
- "of the command word(1)."
- );
-
- DefineProperty("fold", &OptionsHaskell::fold);
-
- DefineProperty("fold.comment", &OptionsHaskell::foldComment);
-
- DefineProperty("fold.compact", &OptionsHaskell::foldCompact);
-
- DefineProperty("fold.haskell.imports", &OptionsHaskell::foldImports,
- "Set to 1 to enable folding of import declarations");
-
- DefineWordListSets(haskellWordListDesc);
- }
-};
-
-class LexerHaskell : public ILexer {
- bool literate;
- int firstImportLine;
- int firstImportIndent;
- WordList keywords;
- WordList ffi;
- WordList reserved_operators;
- OptionsHaskell options;
- OptionSetHaskell osHaskell;
-
- enum HashCount {
- oneHash
- ,twoHashes
- ,unlimitedHashes
- };
-
- enum KeywordMode {
- HA_MODE_DEFAULT = 0
- ,HA_MODE_IMPORT1 = 1 // after "import", before "qualified" or "safe" or package name or module name.
- ,HA_MODE_IMPORT2 = 2 // after module name, before "as" or "hiding".
- ,HA_MODE_IMPORT3 = 3 // after "as", before "hiding"
- ,HA_MODE_MODULE = 4 // after "module", before module name.
- ,HA_MODE_FFI = 5 // after "foreign", before FFI keywords
- ,HA_MODE_TYPE = 6 // after "type" or "data", before "family"
- };
-
- enum LiterateMode {
- LITERATE_BIRD = 0 // if '>' is the first character on the line,
- // color '>' as a codedelim and the rest of
- // the line as code.
- // else if "\begin{code}" is the only word on the
- // line except whitespace, switch to LITERATE_BLOCK
- // otherwise color the line as a literate comment.
- ,LITERATE_BLOCK = 1 // if the string "\end{code}" is encountered at column
- // 0 ignoring all later characters, color the line
- // as a codedelim and switch to LITERATE_BIRD
- // otherwise color the line as code.
- };
-
- struct HaskellLineInfo {
- unsigned int nestLevel; // 22 bits ought to be enough for anybody
- unsigned int nonexternalStyle; // 5 bits, widen if number of styles goes
- // beyond 31.
- bool pragma;
- LiterateMode lmode;
- KeywordMode mode;
-
- HaskellLineInfo(int state) :
- nestLevel (state >> 10)
- , nonexternalStyle ((state >> 5) & 0x1F)
- , pragma ((state >> 4) & 0x1)
- , lmode (static_cast<LiterateMode>((state >> 3) & 0x1))
- , mode (static_cast<KeywordMode>(state & 0x7))
- {}
-
- int ToLineState() {
- return
- (nestLevel << 10)
- | (nonexternalStyle << 5)
- | (pragma << 4)
- | (lmode << 3)
- | mode;
- }
- };
-
- inline void skipMagicHash(StyleContext &sc, const HashCount hashes) const {
- if (options.magicHash && sc.ch == '#') {
- sc.Forward();
- if (hashes == twoHashes && sc.ch == '#') {
- sc.Forward();
- } else if (hashes == unlimitedHashes) {
- while (sc.ch == '#') {
- sc.Forward();
- }
- }
- }
- }
-
- bool LineContainsImport(const int line, Accessor &styler) const {
- if (options.foldImports) {
- int currentPos = styler.LineStart(line);
- int style = styler.StyleAt(currentPos);
-
- int eol_pos = styler.LineStart(line + 1) - 1;
-
- while (currentPos < eol_pos) {
- int ch = styler[currentPos];
- style = styler.StyleAt(currentPos);
-
- if (ch == ' ' || ch == '\t'
- || IsCommentBlockStyle(style)
- || style == SCE_HA_LITERATE_CODEDELIM) {
- currentPos++;
- } else {
- break;
- }
- }
-
- return (style == SCE_HA_KEYWORD
- && styler.Match(currentPos, "import"));
- } else {
- return false;
- }
- }
-
- inline int IndentAmountWithOffset(Accessor &styler, const int line) const {
- const int indent = HaskellIndentAmount(styler, line);
- const int indentLevel = indent & SC_FOLDLEVELNUMBERMASK;
- return indentLevel <= ((firstImportIndent - 1) + SC_FOLDLEVELBASE)
- ? indent
- : (indentLevel + firstImportIndent) | (indent & ~SC_FOLDLEVELNUMBERMASK);
- }
-
- inline int IndentLevelRemoveIndentOffset(const int indentLevel) const {
- return indentLevel <= ((firstImportIndent - 1) + SC_FOLDLEVELBASE)
- ? indentLevel
- : indentLevel - firstImportIndent;
- }
-
-public:
- LexerHaskell(bool literate_)
- : literate(literate_)
- , firstImportLine(-1)
- , firstImportIndent(0)
- {}
- virtual ~LexerHaskell() {}
-
- void SCI_METHOD Release() {
- delete this;
- }
-
- int SCI_METHOD Version() const {
- return lvOriginal;
- }
-
- const char * SCI_METHOD PropertyNames() {
- return osHaskell.PropertyNames();
- }
-
- int SCI_METHOD PropertyType(const char *name) {
- return osHaskell.PropertyType(name);
- }
-
- const char * SCI_METHOD DescribeProperty(const char *name) {
- return osHaskell.DescribeProperty(name);
- }
-
- int SCI_METHOD PropertySet(const char *key, const char *val);
-
- const char * SCI_METHOD DescribeWordListSets() {
- return osHaskell.DescribeWordListSets();
- }
-
- int SCI_METHOD WordListSet(int n, const char *wl);
-
- void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
-
- void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
-
- void * SCI_METHOD PrivateCall(int, void *) {
- return 0;
- }
-
- static ILexer *LexerFactoryHaskell() {
- return new LexerHaskell(false);
- }
-
- static ILexer *LexerFactoryLiterateHaskell() {
- return new LexerHaskell(true);
- }
-};
-
-int SCI_METHOD LexerHaskell::PropertySet(const char *key, const char *val) {
- if (osHaskell.PropertySet(&options, key, val)) {
- return 0;
- }
- return -1;
-}
-
-int SCI_METHOD LexerHaskell::WordListSet(int n, const char *wl) {
- WordList *wordListN = 0;
- switch (n) {
- case 0:
- wordListN = &keywords;
- break;
- case 1:
- wordListN = &ffi;
- break;
- case 2:
- wordListN = &reserved_operators;
- break;
- }
- int firstModification = -1;
- if (wordListN) {
- WordList wlNew;
- wlNew.Set(wl);
- if (*wordListN != wlNew) {
- wordListN->Set(wl);
- firstModification = 0;
- }
- }
- return firstModification;
-}
-
-void SCI_METHOD LexerHaskell::Lex(unsigned int startPos, int length, int initStyle
- ,IDocument *pAccess) {
- LexAccessor styler(pAccess);
-
- int lineCurrent = styler.GetLine(startPos);
-
- HaskellLineInfo hs = HaskellLineInfo(lineCurrent ? styler.GetLineState(lineCurrent-1) : 0);
-
- // Do not leak onto next line
- if (initStyle == SCE_HA_STRINGEOL)
- initStyle = SCE_HA_DEFAULT;
- else if (initStyle == SCE_HA_LITERATE_CODEDELIM)
- initStyle = hs.nonexternalStyle;
-
- StyleContext sc(startPos, length, initStyle, styler);
-
- int base = 10;
- bool dot = false;
-
- bool inDashes = false;
- bool alreadyInTheMiddleOfOperator = false;
-
- assert(!(IsCommentBlockStyle(initStyle) && hs.nestLevel == 0));
-
- while (sc.More()) {
- // Check for state end
-
- if (!IsExternalStyle(sc.state)) {
- hs.nonexternalStyle = sc.state;
- }
-
- // For lexer to work, states should unconditionally forward at least one
- // character.
- // If they don't, they should still check if they are at line end and
- // forward if so.
- // If a state forwards more than one character, it should check every time
- // that it is not a line end and cease forwarding otherwise.
- if (sc.atLineEnd) {
- // Remember the line state for future incremental lexing
- styler.SetLineState(lineCurrent, hs.ToLineState());
- lineCurrent++;
- }
-
- // Handle line continuation generically.
- if (sc.ch == '\\' && (sc.chNext == '\n' || sc.chNext == '\r')
- && ( sc.state == SCE_HA_STRING
- || sc.state == SCE_HA_PREPROCESSOR)) {
- // Remember the line state for future incremental lexing
- styler.SetLineState(lineCurrent, hs.ToLineState());
- lineCurrent++;
-
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
- sc.Forward();
-
- continue;
- }
-
- if (sc.atLineStart) {
-
- if (sc.state == SCE_HA_STRING || sc.state == SCE_HA_CHARACTER) {
- // Prevent SCE_HA_STRINGEOL from leaking back to previous line
- sc.SetState(sc.state);
- }
-
- if (literate && hs.lmode == LITERATE_BIRD) {
- if (!IsExternalStyle(sc.state)) {
- sc.SetState(SCE_HA_LITERATE_COMMENT);
- }
- }
- }
-
- // External
- // Literate
- if ( literate && hs.lmode == LITERATE_BIRD && sc.atLineStart
- && sc.ch == '>') {
- sc.SetState(SCE_HA_LITERATE_CODEDELIM);
- sc.ForwardSetState(hs.nonexternalStyle);
- }
- else if (literate && hs.lmode == LITERATE_BIRD && sc.atLineStart
- && ( sc.ch == ' ' || sc.ch == '\t'
- || sc.Match("\\begin{code}"))) {
- sc.SetState(sc.state);
-
- while ((sc.ch == ' ' || sc.ch == '\t') && sc.More())
- sc.Forward();
-
- if (sc.Match("\\begin{code}")) {
- sc.Forward(static_cast<int>(strlen("\\begin{code}")));
-
- bool correct = true;
-
- while (!sc.atLineEnd && sc.More()) {
- if (sc.ch != ' ' && sc.ch != '\t') {
- correct = false;
- }
- sc.Forward();
- }
-
- if (correct) {
- sc.ChangeState(SCE_HA_LITERATE_CODEDELIM); // color the line end
- hs.lmode = LITERATE_BLOCK;
- }
- }
- }
- else if (literate && hs.lmode == LITERATE_BLOCK && sc.atLineStart
- && sc.Match("\\end{code}")) {
- sc.SetState(SCE_HA_LITERATE_CODEDELIM);
-
- sc.Forward(static_cast<int>(strlen("\\end{code}")));
-
- while (!sc.atLineEnd && sc.More()) {
- sc.Forward();
- }
-
- sc.SetState(SCE_HA_LITERATE_COMMENT);
- hs.lmode = LITERATE_BIRD;
- }
- // Preprocessor
- else if (sc.atLineStart && sc.ch == '#' && options.cpp
- && (!options.stylingWithinPreprocessor || sc.state == SCE_HA_DEFAULT)) {
- sc.SetState(SCE_HA_PREPROCESSOR);
- sc.Forward();
- }
- // Literate
- else if (sc.state == SCE_HA_LITERATE_COMMENT) {
- sc.Forward();
- }
- else if (sc.state == SCE_HA_LITERATE_CODEDELIM) {
- sc.ForwardSetState(hs.nonexternalStyle);
- }
- // Preprocessor
- else if (sc.state == SCE_HA_PREPROCESSOR) {
- if (sc.atLineEnd) {
- sc.SetState(options.stylingWithinPreprocessor
- ? SCE_HA_DEFAULT
- : hs.nonexternalStyle);
- sc.Forward(); // prevent double counting a line
- } else if (options.stylingWithinPreprocessor && !IsHaskellLetter(sc.ch)) {
- sc.SetState(SCE_HA_DEFAULT);
- } else {
- sc.Forward();
- }
- }
- // Haskell
- // Operator
- else if (sc.state == SCE_HA_OPERATOR) {
- int style = SCE_HA_OPERATOR;
-
- if ( sc.ch == ':'
- && !alreadyInTheMiddleOfOperator
- // except "::"
- && !( sc.chNext == ':'
- && !IsAnHaskellOperatorChar(sc.GetRelative(2)))) {
- style = SCE_HA_CAPITAL;
- }
-
- alreadyInTheMiddleOfOperator = false;
-
- while (IsAnHaskellOperatorChar(sc.ch))
- sc.Forward();
-
- char s[100];
- sc.GetCurrent(s, sizeof(s));
-
- if (reserved_operators.InList(s))
- style = SCE_HA_RESERVED_OPERATOR;
-
- sc.ChangeState(style);
- sc.SetState(SCE_HA_DEFAULT);
- }
- // String
- else if (sc.state == SCE_HA_STRING) {
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_HA_STRINGEOL);
- sc.ForwardSetState(SCE_HA_DEFAULT);
- } else if (sc.ch == '\"') {
- sc.Forward();
- skipMagicHash(sc, oneHash);
- sc.SetState(SCE_HA_DEFAULT);
- } else if (sc.ch == '\\') {
- sc.Forward(2);
- } else {
- sc.Forward();
- }
- }
- // Char
- else if (sc.state == SCE_HA_CHARACTER) {
- if (sc.atLineEnd) {
- sc.ChangeState(SCE_HA_STRINGEOL);
- sc.ForwardSetState(SCE_HA_DEFAULT);
- } else if (sc.ch == '\'') {
- sc.Forward();
- skipMagicHash(sc, oneHash);
- sc.SetState(SCE_HA_DEFAULT);
- } else if (sc.ch == '\\') {
- sc.Forward(2);
- } else {
- sc.Forward();
- }
- }
- // Number
- else if (sc.state == SCE_HA_NUMBER) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_HA_DEFAULT);
- sc.Forward(); // prevent double counting a line
- } else if (IsADigit(sc.ch, base)) {
- sc.Forward();
- } else if (sc.ch=='.' && dot && IsADigit(sc.chNext, base)) {
- sc.Forward(2);
- dot = false;
- } else if ((base == 10) &&
- (sc.ch == 'e' || sc.ch == 'E') &&
- (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) {
- sc.Forward();
- if (sc.ch == '+' || sc.ch == '-')
- sc.Forward();
- } else {
- skipMagicHash(sc, twoHashes);
- sc.SetState(SCE_HA_DEFAULT);
- }
- }
- // Keyword or Identifier
- else if (sc.state == SCE_HA_IDENTIFIER) {
- int style = IsHaskellUpperCase(sc.ch) ? SCE_HA_CAPITAL : SCE_HA_IDENTIFIER;
-
- assert(IsAHaskellWordStart(sc.ch));
-
- sc.Forward();
-
- while (sc.More()) {
- if (IsAHaskellWordChar(sc.ch)) {
- sc.Forward();
- } else if (sc.ch == '.' && style == SCE_HA_CAPITAL) {
- if (IsHaskellUpperCase(sc.chNext)) {
- sc.Forward();
- style = SCE_HA_CAPITAL;
- } else if (IsAHaskellWordStart(sc.chNext)) {
- sc.Forward();
- style = SCE_HA_IDENTIFIER;
- } else if (IsAnHaskellOperatorChar(sc.chNext)) {
- sc.Forward();
- style = sc.ch == ':' ? SCE_HA_CAPITAL : SCE_HA_OPERATOR;
- while (IsAnHaskellOperatorChar(sc.ch))
- sc.Forward();
- break;
- } else {
- break;
- }
- } else {
- break;
- }
- }
-
- skipMagicHash(sc, unlimitedHashes);
-
- char s[100];
- sc.GetCurrent(s, sizeof(s));
-
- KeywordMode new_mode = HA_MODE_DEFAULT;
-
- if (keywords.InList(s)) {
- style = SCE_HA_KEYWORD;
- } else if (style == SCE_HA_CAPITAL) {
- if (hs.mode == HA_MODE_IMPORT1 || hs.mode == HA_MODE_IMPORT3) {
- style = SCE_HA_MODULE;
- new_mode = HA_MODE_IMPORT2;
- } else if (hs.mode == HA_MODE_MODULE) {
- style = SCE_HA_MODULE;
- }
- } else if (hs.mode == HA_MODE_IMPORT1 &&
- strcmp(s,"qualified") == 0) {
- style = SCE_HA_KEYWORD;
- new_mode = HA_MODE_IMPORT1;
- } else if (options.highlightSafe &&
- hs.mode == HA_MODE_IMPORT1 &&
- strcmp(s,"safe") == 0) {
- style = SCE_HA_KEYWORD;
- new_mode = HA_MODE_IMPORT1;
- } else if (hs.mode == HA_MODE_IMPORT2) {
- if (strcmp(s,"as") == 0) {
- style = SCE_HA_KEYWORD;
- new_mode = HA_MODE_IMPORT3;
- } else if (strcmp(s,"hiding") == 0) {
- style = SCE_HA_KEYWORD;
- }
- } else if (hs.mode == HA_MODE_TYPE) {
- if (strcmp(s,"family") == 0)
- style = SCE_HA_KEYWORD;
- }
-
- if (hs.mode == HA_MODE_FFI) {
- if (ffi.InList(s)) {
- style = SCE_HA_KEYWORD;
- new_mode = HA_MODE_FFI;
- }
- }
-
- sc.ChangeState(style);
- sc.SetState(SCE_HA_DEFAULT);
-
- if (strcmp(s,"import") == 0 && hs.mode != HA_MODE_FFI)
- new_mode = HA_MODE_IMPORT1;
- else if (strcmp(s,"module") == 0)
- new_mode = HA_MODE_MODULE;
- else if (strcmp(s,"foreign") == 0)
- new_mode = HA_MODE_FFI;
- else if (strcmp(s,"type") == 0
- || strcmp(s,"data") == 0)
- new_mode = HA_MODE_TYPE;
-
- hs.mode = new_mode;
- }
-
- // Comments
- // Oneliner
- else if (sc.state == SCE_HA_COMMENTLINE) {
- if (sc.atLineEnd) {
- sc.SetState(hs.pragma ? SCE_HA_PRAGMA : SCE_HA_DEFAULT);
- sc.Forward(); // prevent double counting a line
- } else if (inDashes && sc.ch != '-' && !hs.pragma) {
- inDashes = false;
- if (IsAnHaskellOperatorChar(sc.ch)) {
- alreadyInTheMiddleOfOperator = true;
- sc.ChangeState(SCE_HA_OPERATOR);
- }
- } else {
- sc.Forward();
- }
- }
- // Nested
- else if (IsCommentBlockStyle(sc.state)) {
- if (sc.Match('{','-')) {
- sc.SetState(CommentBlockStyleFromNestLevel(hs.nestLevel));
- sc.Forward(2);
- hs.nestLevel++;
- } else if (sc.Match('-','}')) {
- sc.Forward(2);
- assert(hs.nestLevel > 0);
- if (hs.nestLevel > 0)
- hs.nestLevel--;
- sc.SetState(
- hs.nestLevel == 0
- ? (hs.pragma ? SCE_HA_PRAGMA : SCE_HA_DEFAULT)
- : CommentBlockStyleFromNestLevel(hs.nestLevel - 1));
- } else {
- sc.Forward();
- }
- }
- // Pragma
- else if (sc.state == SCE_HA_PRAGMA) {
- if (sc.Match("#-}")) {
- hs.pragma = false;
- sc.Forward(3);
- sc.SetState(SCE_HA_DEFAULT);
- } else if (sc.Match('-','-')) {
- sc.SetState(SCE_HA_COMMENTLINE);
- sc.Forward(2);
- inDashes = false;
- } else if (sc.Match('{','-')) {
- sc.SetState(CommentBlockStyleFromNestLevel(hs.nestLevel));
- sc.Forward(2);
- hs.nestLevel = 1;
- } else {
- sc.Forward();
- }
- }
- // New state?
- else if (sc.state == SCE_HA_DEFAULT) {
- // Digit
- if (IsADigit(sc.ch)) {
- hs.mode = HA_MODE_DEFAULT;
-
- sc.SetState(SCE_HA_NUMBER);
- if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) {
- // Match anything starting with "0x" or "0X", too
- sc.Forward(2);
- base = 16;
- dot = false;
- } else if (sc.ch == '0' && (sc.chNext == 'O' || sc.chNext == 'o')) {
- // Match anything starting with "0o" or "0O", too
- sc.Forward(2);
- base = 8;
- dot = false;
- } else {
- sc.Forward();
- base = 10;
- dot = true;
- }
- }
- // Pragma
- else if (sc.Match("{-#")) {
- hs.pragma = true;
- sc.SetState(SCE_HA_PRAGMA);
- sc.Forward(3);
- }
- // Comment line
- else if (sc.Match('-','-')) {
- sc.SetState(SCE_HA_COMMENTLINE);
- sc.Forward(2);
- inDashes = true;
- }
- // Comment block
- else if (sc.Match('{','-')) {
- sc.SetState(CommentBlockStyleFromNestLevel(hs.nestLevel));
- sc.Forward(2);
- hs.nestLevel = 1;
- }
- // String
- else if (sc.ch == '\"') {
- sc.SetState(SCE_HA_STRING);
- sc.Forward();
- }
- // Character or quoted name or promoted term
- else if (sc.ch == '\'') {
- hs.mode = HA_MODE_DEFAULT;
-
- sc.SetState(SCE_HA_CHARACTER);
- sc.Forward();
-
- if (options.allowQuotes) {
- // Quoted type ''T
- if (sc.ch=='\'' && IsAHaskellWordStart(sc.chNext)) {
- sc.Forward();
- sc.ChangeState(SCE_HA_IDENTIFIER);
- } else if (sc.chNext != '\'') {
- // Quoted name 'n or promoted constructor 'N
- if (IsAHaskellWordStart(sc.ch)) {
- sc.ChangeState(SCE_HA_IDENTIFIER);
- // Promoted constructor operator ':~>
- } else if (sc.ch == ':') {
- alreadyInTheMiddleOfOperator = false;
- sc.ChangeState(SCE_HA_OPERATOR);
- // Promoted list or tuple '[T]
- } else if (sc.ch == '[' || sc.ch== '(') {
- sc.ChangeState(SCE_HA_OPERATOR);
- sc.ForwardSetState(SCE_HA_DEFAULT);
- }
- }
- }
- }
- // Operator starting with '?' or an implicit parameter
- else if (sc.ch == '?') {
- hs.mode = HA_MODE_DEFAULT;
-
- alreadyInTheMiddleOfOperator = false;
- sc.SetState(SCE_HA_OPERATOR);
-
- if ( options.implicitParams
- && IsAHaskellWordStart(sc.chNext)
- && !IsHaskellUpperCase(sc.chNext)) {
- sc.Forward();
- sc.ChangeState(SCE_HA_IDENTIFIER);
- }
- }
- // Operator
- else if (IsAnHaskellOperatorChar(sc.ch)) {
- hs.mode = HA_MODE_DEFAULT;
-
- sc.SetState(SCE_HA_OPERATOR);
- }
- // Braces and punctuation
- else if (sc.ch == ',' || sc.ch == ';'
- || sc.ch == '(' || sc.ch == ')'
- || sc.ch == '[' || sc.ch == ']'
- || sc.ch == '{' || sc.ch == '}') {
- sc.SetState(SCE_HA_OPERATOR);
- sc.ForwardSetState(SCE_HA_DEFAULT);
- }
- // Keyword or Identifier
- else if (IsAHaskellWordStart(sc.ch)) {
- sc.SetState(SCE_HA_IDENTIFIER);
- // Something we don't care about
- } else {
- sc.Forward();
- }
- }
- // This branch should never be reached.
- else {
- assert(false);
- sc.Forward();
- }
- }
- sc.Complete();
-}
-
-void SCI_METHOD LexerHaskell::Fold(unsigned int startPos, int length, int // initStyle
- ,IDocument *pAccess) {
- if (!options.fold)
- return;
-
- Accessor styler(pAccess, NULL);
-
- int lineCurrent = styler.GetLine(startPos);
-
- if (lineCurrent <= firstImportLine) {
- firstImportLine = -1; // readjust first import position
- firstImportIndent = 0;
- }
-
- const int maxPos = startPos + length;
- const int maxLines =
- maxPos == styler.Length()
- ? styler.GetLine(maxPos)
- : styler.GetLine(maxPos - 1); // Requested last line
- const int docLines = styler.GetLine(styler.Length()); // Available last line
-
- // Backtrack to previous non-blank line so we can determine indent level
- // for any white space lines
- // and so we can fix any preceding fold level (which is why we go back
- // at least one line in all cases)
- bool importHere = LineContainsImport(lineCurrent, styler);
- int indentCurrent = IndentAmountWithOffset(styler, lineCurrent);
-
- while (lineCurrent > 0) {
- lineCurrent--;
- importHere = LineContainsImport(lineCurrent, styler);
- indentCurrent = IndentAmountWithOffset(styler, lineCurrent);
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG))
- break;
- }
-
- int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
-
- if (importHere) {
- indentCurrentLevel = IndentLevelRemoveIndentOffset(indentCurrentLevel);
- if (firstImportLine == -1) {
- firstImportLine = lineCurrent;
- firstImportIndent = (1 + indentCurrentLevel) - SC_FOLDLEVELBASE;
- }
- if (firstImportLine != lineCurrent) {
- indentCurrentLevel++;
- }
- }
-
- indentCurrent = indentCurrentLevel | (indentCurrent & ~SC_FOLDLEVELNUMBERMASK);
-
- // Process all characters to end of requested range
- //that hangs over the end of the range. Cap processing in all cases
- // to end of document.
- while (lineCurrent <= docLines && lineCurrent <= maxLines) {
-
- // Gather info
- int lineNext = lineCurrent + 1;
- importHere = false;
- int indentNext = indentCurrent;
-
- if (lineNext <= docLines) {
- // Information about next line is only available if not at end of document
- importHere = LineContainsImport(lineNext, styler);
- indentNext = IndentAmountWithOffset(styler, lineNext);
- }
- if (indentNext & SC_FOLDLEVELWHITEFLAG)
- indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;
-
- // Skip past any blank lines for next indent level info; we skip also
- // comments (all comments, not just those starting in column 0)
- // which effectively folds them into surrounding code rather
- // than screwing up folding.
-
- while (lineNext < docLines && (indentNext & SC_FOLDLEVELWHITEFLAG)) {
- lineNext++;
- importHere = LineContainsImport(lineNext, styler);
- indentNext = IndentAmountWithOffset(styler, lineNext);
- }
-
- int indentNextLevel = indentNext & SC_FOLDLEVELNUMBERMASK;
-
- if (importHere) {
- indentNextLevel = IndentLevelRemoveIndentOffset(indentNextLevel);
- if (firstImportLine == -1) {
- firstImportLine = lineNext;
- firstImportIndent = (1 + indentNextLevel) - SC_FOLDLEVELBASE;
- }
- if (firstImportLine != lineNext) {
- indentNextLevel++;
- }
- }
-
- indentNext = indentNextLevel | (indentNext & ~SC_FOLDLEVELNUMBERMASK);
-
- const int levelBeforeComments = Maximum(indentCurrentLevel,indentNextLevel);
-
- // Now set all the indent levels on the lines we skipped
- // Do this from end to start. Once we encounter one line
- // which is indented more than the line after the end of
- // the comment-block, use the level of the block before
-
- int skipLine = lineNext;
- int skipLevel = indentNextLevel;
-
- while (--skipLine > lineCurrent) {
- int skipLineIndent = IndentAmountWithOffset(styler, skipLine);
-
- if (options.foldCompact) {
- if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > indentNextLevel) {
- skipLevel = levelBeforeComments;
- }
-
- int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
-
- styler.SetLevel(skipLine, skipLevel | whiteFlag);
- } else {
- if ( (skipLineIndent & SC_FOLDLEVELNUMBERMASK) > indentNextLevel
- && !(skipLineIndent & SC_FOLDLEVELWHITEFLAG)) {
- skipLevel = levelBeforeComments;
- }
-
- styler.SetLevel(skipLine, skipLevel);
- }
- }
-
- int lev = indentCurrent;
-
- if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
- lev |= SC_FOLDLEVELHEADERFLAG;
- }
-
- // Set fold level for this line and move to next line
- styler.SetLevel(lineCurrent, options.foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);
-
- indentCurrent = indentNext;
- indentCurrentLevel = indentNextLevel;
- lineCurrent = lineNext;
- }
-
- // NOTE: Cannot set level of last line here because indentCurrent doesn't have
- // header flag set; the loop above is crafted to take care of this case!
- //styler.SetLevel(lineCurrent, indentCurrent);
-}
-
-LexerModule lmHaskell(SCLEX_HASKELL, LexerHaskell::LexerFactoryHaskell, "haskell", haskellWordListDesc);
-LexerModule lmLiterateHaskell(SCLEX_LITERATEHASKELL, LexerHaskell::LexerFactoryLiterateHaskell, "literatehaskell", haskellWordListDesc);