diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/KeyWords.cxx | 1 | ||||
| -rw-r--r-- | src/LexSmalltalk.cxx | 345 | 
2 files changed, 346 insertions, 0 deletions
| diff --git a/src/KeyWords.cxx b/src/KeyWords.cxx index 01fe0fd4e..cee412b1e 100644 --- a/src/KeyWords.cxx +++ b/src/KeyWords.cxx @@ -190,6 +190,7 @@ int Scintilla_LinkLexers() {  	LINK_LEXER(lmREBOL);  	LINK_LEXER(lmRuby);  	LINK_LEXER(lmScriptol); +	LINK_LEXER(lmSmalltalk);  	LINK_LEXER(lmSpecman);  	LINK_LEXER(lmSQL);  	LINK_LEXER(lmTADS3); diff --git a/src/LexSmalltalk.cxx b/src/LexSmalltalk.cxx new file mode 100644 index 000000000..159390041 --- /dev/null +++ b/src/LexSmalltalk.cxx @@ -0,0 +1,345 @@ +// Scintilla source code edit control +/** @file LexSmalltalk.cxx + ** Lexer for Smalltalk language. + ** Written by Sergey Philippov, sphilippov-at-gmail-dot-com + **/ +// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> +// The License.txt file describes the conditions under which this software may be distributed. + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +/* +| lexTable classificationBlock charClasses | +charClasses := #(#DecDigit #Letter #Special #Upper #BinSel). +lexTable := ByteArray new: 128. +classificationBlock := [ :charClass :chars | +    | flag | +    flag := 1 bitShift: (charClasses indexOf: charClass) - 1. +    chars do: [ :char | lexTable at: char codePoint + 1 put: ((lexTable at: char codePoint + 1) bitOr: flag)]]. + +classificationBlock +    value: #DecDigit value: '0123456789'; +    value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; +    value: #Special value: '()[]{};.^:'; +    value: #BinSel value: '~@%&*-+=|\/,<>?!'; +    value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. + +((String new: 500) streamContents: [ :stream |             +    stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'. +    lexTable keysAndValuesDo: [ :index :value | +        ((index - 1) rem: 16) == 0 ifTrue: [ +            stream crLf; tab] +        ifFalse: [ +            stream space]. +        stream print: value. +        index ~= 256 ifTrue: [ +            stream nextPut: $,]]. +    stream crLf; nextPutAll: '};'; crLf. +     +    charClasses keysAndValuesDo: [ :index :name | +        stream +            crLf; +            nextPutAll: ( +                ('static inline bool is<1s>(int ch) {return (ch > 0) && (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}') +                    expandMacrosWith: name with: (1 bitShift: (index - 1))) +    ]]) edit +*/ + +// autogenerated {{{{ + +static int ClassificationTable[256] = { +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +    0, 16, 0, 0, 0, 16, 16, 0, 4, 4, 16, 16, 16, 16, 4, 16, +    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 16, 16, 16, 16, +    16, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 16, 4, 4, 2, +    0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 16, 4, 16, 0, +}; + +static inline bool isDecDigit(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 1) != 0);} +static inline bool isLetter(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 2) != 0);} +static inline bool isSpecial(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 4) != 0);} +static inline bool isUpper(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 8) != 0);} +static inline bool isBinSel(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 16) != 0);} +// autogenerated }}}} + +static inline bool isAlphaNumeric(int ch) { +    return isDecDigit(ch) || isLetter(ch); +} + +static inline bool isDigitOfRadix(int ch, int radix) +{ +    if (isDecDigit(ch)) +        return (ch - '0') < radix; +    else if (!isUpper(ch)) +        return false; +    else +        return (ch - 'A' + 10) < radix; +} + +static inline void skipComment(StyleContext& sc) +{     +    while (sc.More() && sc.ch != '\"') +        sc.Forward(); +} + +static inline void skipString(StyleContext& sc) +{ +    while (sc.More()) { +        if (sc.ch == '\'') { +            if (sc.chNext != '\'') +                return; +            sc.Forward(); +        } +        sc.Forward(); +    } +} + +static void handleHash(StyleContext& sc) +{ +    if (isSpecial(sc.chNext)) { +        sc.SetState(SCE_ST_SPECIAL); +        return; +    } +     +    sc.SetState(SCE_ST_SYMBOL); +    sc.Forward(); +    if (sc.ch == '\'') { +        sc.Forward(); +        skipString(sc); +    } +    else { +        if (isLetter(sc.ch)) { +            while (isAlphaNumeric(sc.chNext) || sc.chNext == ':') +                sc.Forward(); +        } +        else if (isBinSel(sc.ch)) { +            while (isBinSel(sc.chNext)) +                sc.Forward(); +        } +    } +} + +static inline void handleSpecial(StyleContext& sc) +{ +    if (sc.ch == ':' && sc.chNext == '=') { +        sc.SetState(SCE_ST_ASSIGN); +        sc.Forward(); +    } +    else { +        if (sc.ch == '^') +            sc.SetState(SCE_ST_RETURN); +        else +            sc.SetState(SCE_ST_SPECIAL); +    } +} + +static inline void skipInt(StyleContext& sc, int radix) +{ +    while (isDigitOfRadix(sc.chNext, radix)) +        sc.Forward(); +} + +static void handleNumeric(StyleContext& sc) +{ +    char num[256]; +    int nl; +    int radix; +     +    sc.SetState(SCE_ST_NUMBER); +    num[0] = static_cast<char>(sc.ch); +    nl = 1; +    while (isDecDigit(sc.chNext)) { +        num[nl++] = static_cast<char>(sc.chNext); +        sc.Forward(); +        if (nl+1 == sizeof(num)/sizeof(num[0])) // overrun check +            break; +    } +    if (sc.chNext == 'r') { +        num[nl] = 0; +        if (num[0] == '-') +            radix = atoi(num + 1); +        else +            radix = atoi(num); +        sc.Forward(); +        if (sc.chNext == '-') +            sc.Forward(); +        skipInt(sc, radix); +    } +    else +        radix = 10; +    if (sc.chNext != '.' || !isDigitOfRadix(sc.GetRelative(2), radix)) +        return; +    sc.Forward(); +    skipInt(sc, radix); +    if (sc.chNext == 's') { +        // ScaledDecimal +        sc.Forward(); +        while (isDecDigit(sc.chNext)) +            sc.Forward(); +        return; +    } +    else if (sc.chNext != 'e' && sc.chNext != 'd' && sc.chNext != 'q') +        return; +    sc.Forward(); +    if (sc.chNext == '+' || sc.chNext == '-') +        sc.Forward(); +    skipInt(sc, radix); +} + +static inline void handleBinSel(StyleContext& sc) +{ +    sc.SetState(SCE_ST_BINARY); +    while (isBinSel(sc.chNext)) +        sc.Forward(); +} + +static const char* SpecialKwSelectors[] = { +    "ifTrue:", +    "ifFalse:", +    "whileTrue:", +    "whileFalse:", +    "ifNil:", +    "ifNotNil:", +    NULL +}; + +static const char* SpecialUnarySelectors[] = { +    "whileTrue", +    "whileFalse", +    "repeat", +    NULL +}; + +static inline bool isSpecialSelector(const char* sel, const char** sels) +{ +    int i; +     +    for (i = 0; sels[i] != NULL; i++) { +        if (!strcmp(sel, sels[i])) +            return true; +    } +    return false; +} + +static void handleLetter(StyleContext& sc) +{ +    char ident[256]; +    int il; +    int state; +    bool doubleColonPresent; +     +    sc.SetState(SCE_ST_DEFAULT); + +    ident[0] = static_cast<char>(sc.ch); +    il = 1; +    doubleColonPresent; +    while (isAlphaNumeric(sc.chNext)) { +        ident[il++] = static_cast<char>(sc.chNext); +        sc.Forward(); +        if (il+2 == sizeof(ident)/sizeof(ident[0])) // overrun check +            break; +    } + +    if (sc.chNext == ':') { +        doubleColonPresent = true; +        ident[il++] = ':'; +        sc.Forward(); +    } +    else +        doubleColonPresent = false; +    ident[il] = 0; +     +    if (doubleColonPresent) { +        if (isSpecialSelector(ident, SpecialKwSelectors)) +            state = SCE_ST_SPEC_SEL; +        else +            state = SCE_ST_KWSEND; +    } +    else if (isUpper(ident[0])) +        state = SCE_ST_GLOBAL; +    else if (isSpecialSelector(ident, SpecialUnarySelectors)) +        state = SCE_ST_SPEC_SEL; +    else { +        if (!strcmp(ident, "self")) +            state = SCE_ST_SELF; +        else if (!strcmp(ident, "super")) +            state = SCE_ST_SUPER; +        else if (!strcmp(ident, "nil")) +            state = SCE_ST_NIL; +        else if (!strcmp(ident, "true") || !strcmp(ident, "false")) +            state = SCE_ST_BOOL; +        else +            state = SCE_ST_DEFAULT; +    } +     +    sc.ChangeState(state); +} + +static void colorizeSmalltalkDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) +{ +    StyleContext sc(startPos, length, initStyle, styler); + +    if (initStyle == SCE_ST_COMMENT) { +        skipComment(sc); +        if (sc.More()) +            sc.Forward(); +    } +    else if (initStyle == SCE_ST_STRING) { +        skipString(sc); +        if (sc.More()) +            sc.Forward(); +    } + +    for (; sc.More(); sc.Forward()) { +        int ch; +         +        ch = sc.ch; +        if (ch == '\"') { +            sc.SetState(SCE_ST_COMMENT); +            sc.Forward(); +            skipComment(sc); +        } +        else if (ch == '\'') { +            sc.SetState(SCE_ST_STRING); +            sc.Forward(); +            skipString(sc); +        } +        else if (ch == '#') +            handleHash(sc); +        else if (ch == '$') { +            sc.SetState(SCE_ST_CHARACTER); +            sc.Forward(); +        } +        else if (isSpecial(ch)) +            handleSpecial(sc); +        else if (isDecDigit(ch)) +            handleNumeric(sc); +        else if (isLetter(ch)) +            handleLetter(sc); +        else if (isBinSel(ch)) { +            if (ch == '-' && isDecDigit(sc.chNext)) +                handleNumeric(sc); +            else +                handleBinSel(sc); +        } +        else +            sc.SetState(SCE_ST_DEFAULT); +    } +    sc.Complete(); +} + +LexerModule lmSmalltalk(SCLEX_SMALLTALK, colorizeSmalltalkDoc, "smalltalk"); | 
