diff options
| -rw-r--r-- | doc/ScintillaHistory.html | 1 | ||||
| -rw-r--r-- | include/SciLexer.h | 20 | ||||
| -rw-r--r-- | include/Scintilla.iface | 22 | ||||
| -rw-r--r-- | lexers/LexA68k.cxx | 319 | ||||
| -rw-r--r-- | src/Catalogue.cxx | 1 | ||||
| -rw-r--r-- | win32/scintilla.mak | 3 | ||||
| -rw-r--r-- | win32/scintilla_vc6.mak | 3 | 
7 files changed, 369 insertions, 0 deletions
| diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 5775acd75..2aac5c34d 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -359,6 +359,7 @@  	<td>Michael Mullin</td>  	<td>Carlos SS</td>  	<td>vim</td> +	<td>Martial Demolins</td>      </tr>      </table>      <p> diff --git a/include/SciLexer.h b/include/SciLexer.h index 3aa2c3853..ea49be2c9 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -112,6 +112,7 @@  #define SCLEX_SML 97  #define SCLEX_MARKDOWN 98  #define SCLEX_TXT2TAGS 99 +#define SCLEX_A68K 100  #define SCLEX_AUTOMATIC 1000  #define SCE_P_DEFAULT 0  #define SCE_P_COMMENTLINE 1 @@ -1415,6 +1416,25 @@  #define SCE_TXT2TAGS_OPTION 23  #define SCE_TXT2TAGS_PREPROC 24  #define SCE_TXT2TAGS_POSTPROC 25 +#define SCE_A68K_DEFAULT 0 +#define SCE_A68K_COMMENT 1 +#define SCE_A68K_NUMBER_DEC 2 +#define SCE_A68K_NUMBER_BIN 3 +#define SCE_A68K_NUMBER_HEX 4 +#define SCE_A68K_STRING1 5 +#define SCE_A68K_OPERATOR 6 +#define SCE_A68K_CPUINSTRUCTION 7 +#define SCE_A68K_EXTINSTRUCTION 8 +#define SCE_A68K_REGISTER 9 +#define SCE_A68K_DIRECTIVE 10 +#define SCE_A68K_MACRO_ARG 11 +#define SCE_A68K_LABEL 12 +#define SCE_A68K_STRING2 13 +#define SCE_A68K_IDENTIFIER 14 +#define SCE_A68K_MACRO_DECLARATION 15 +#define SCE_A68K_COMMENT_WORD 16 +#define SCE_A68K_COMMENT_SPECIAL 17 +#define SCE_A68K_COMMENT_DOXYGEN 18  /* --Autogenerated -- end of section automatically generated from Scintilla.iface */  #endif diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 61031398c..405fc0552 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2335,6 +2335,7 @@ val SCLEX_NIMROD=96  val SCLEX_SML=97  val SCLEX_MARKDOWN=98  val SCLEX_TXT2TAGS=99 +val SCLEX_A68K=100  # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a  # value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -3819,6 +3820,27 @@ val SCE_TXT2TAGS_COMMENT=22  val SCE_TXT2TAGS_OPTION=23  val SCE_TXT2TAGS_PREPROC=24  val SCE_TXT2TAGS_POSTPROC=25 +# Lexical states for SCLEX_A68K +lex A68k=SCLEX_A68K SCE_A68K_ +val SCE_A68K_DEFAULT=0 +val SCE_A68K_COMMENT=1 +val SCE_A68K_NUMBER_DEC=2 +val SCE_A68K_NUMBER_BIN=3 +val SCE_A68K_NUMBER_HEX=4 +val SCE_A68K_STRING1=5 +val SCE_A68K_OPERATOR=6 +val SCE_A68K_CPUINSTRUCTION=7 +val SCE_A68K_EXTINSTRUCTION=8 +val SCE_A68K_REGISTER=9 +val SCE_A68K_DIRECTIVE=10 +val SCE_A68K_MACRO_ARG=11 +val SCE_A68K_LABEL=12 +val SCE_A68K_STRING2=13 +val SCE_A68K_IDENTIFIER=14 +val SCE_A68K_MACRO_DECLARATION=15 +val SCE_A68K_COMMENT_WORD=16 +val SCE_A68K_COMMENT_SPECIAL=17 +val SCE_A68K_COMMENT_DOXYGEN=18  # Events diff --git a/lexers/LexA68k.cxx b/lexers/LexA68k.cxx new file mode 100644 index 000000000..8704fb4db --- /dev/null +++ b/lexers/LexA68k.cxx @@ -0,0 +1,319 @@ +// Scintilla source code edit control +/** @file LexA68k.cxx + ** Lexer for Assembler, just for the MASM syntax + ** Written by Martial Demolins AKA Folco + **/ +// Copyright 2010 Martial Demolins <mdemolins(a)gmail.com> +// The License.txt file describes the conditions under which this software +// may be distributed. + + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> +#include <assert.h> +#include <ctype.h> + +#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 "LexerModule.h" + +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + + +// Return values for GetOperatorType +#define NO_OPERATOR     0 +#define OPERATOR_1CHAR  1 +#define OPERATOR_2CHAR  2 + + +/** + *  IsIdentifierStart + * + *  Return true if the given char is a valid identifier first char + */ + +static inline bool IsIdentifierStart (const int ch) +{ +    return (isalpha(ch) || (ch == '_') || (ch == '\\')); +} + + +/** + *  IsIdentifierChar + * + *  Return true if the given char is a valid identifier char + */ + +static inline bool IsIdentifierChar (const int ch) +{ +    return (isalnum(ch) || (ch == '_') || (ch == '@') || (ch == ':') || (ch == '.')); +} + + +/** + *  GetOperatorType + * + *  Return: + *  NO_OPERATOR     if char is not an operator + *  OPERATOR_1CHAR  if the operator is one char long + *  OPERATOR_2CHAR  if the operator is two chars long + */ + +static inline int GetOperatorType (const int ch1, const int ch2) +{ +    int OpType = NO_OPERATOR; + +    if ((ch1 == '+') || (ch1 == '-') || (ch1 == '*') || (ch1 == '/') || (ch1 == '#') || +        (ch1 == '(') || (ch1 == ')') || (ch1 == '~') || (ch1 == '&') || (ch1 == '|') || (ch1 == ',')) +        OpType = OPERATOR_1CHAR; + +    else if ((ch1 == ch2) && (ch1 == '<' || ch1 == '>')) +        OpType = OPERATOR_2CHAR; + +    return OpType; +} + + +/** + *  IsBin + * + *  Return true if the given char is 0 or 1 + */ + +static inline bool IsBin (const int ch) +{ +    return (ch == '0') || (ch == '1'); +} + + +/** + *  IsDoxygenChar + * + *  Return true if the char may be part of a Doxygen keyword + */ + +static inline bool IsDoxygenChar (const int ch) +{ +    return isalpha(ch) || (ch == '$') || (ch == '[') || (ch == ']') || (ch == '{') || (ch == '}'); +} + + +/** + *  ColouriseA68kDoc + * + *  Main function, which colourises a 68k source + */ + +static void ColouriseA68kDoc (unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) +{ + +    // Get references to keywords lists +    WordList &cpuInstruction = *keywordlists[0]; +    WordList ®isters = *keywordlists[1]; +    WordList &directive = *keywordlists[2]; +    WordList &extInstruction = *keywordlists[3]; +    WordList &commentSpecial = *keywordlists[4]; +    WordList &doxygenKeyword = *keywordlists[5]; + + +    // Instanciate a context for our source +    StyleContext sc(startPos, length, initStyle, styler); + + +    /************************************************************ +    * +    *   Parse the text +    * +    ************************************************************/ + +    for ( ; sc.More(); sc.Forward()) +    { +        char Buffer[100]; +        int OpType; + +        // Reset style at beginning of line +        if (sc.atLineStart) +            sc.SetState(SCE_A68K_DEFAULT); + + +        /************************************************************ +        * +        *   Handle current state if we are not in the "default style" +        * +        ************************************************************/ + +        if (sc.state != SCE_A68K_DEFAULT) +        { +            // Check if current style continue. +            // If this case, we loop because there is nothing else to do +            if (((sc.state == SCE_A68K_NUMBER_DEC) && isdigit(sc.ch))                                       // Decimal number +                || ((sc.state == SCE_A68K_NUMBER_BIN) && IsBin(sc.ch))                                      // Binary number +                || ((sc.state == SCE_A68K_NUMBER_HEX) && isxdigit(sc.ch))                                   // Hexa number +                || ((sc.state == SCE_A68K_MACRO_ARG)  && isdigit(sc.ch))                                    // Arg of macro +                || ((sc.state == SCE_A68K_STRING1)    && (sc.ch != '\''))                                   // String single-quoted +                || ((sc.state == SCE_A68K_STRING2)    && (sc.ch != '\"'))                                   // String double-quoted +                || ((sc.state == SCE_A68K_MACRO_ARG)  && isdigit(sc.ch))                                    // Macro argument +                // Label. ' ' and '\t' are needed to handle macro declarations +                || ((sc.state == SCE_A68K_LABEL)      && (sc.ch != ':') && (sc.ch != ' ') && (sc.ch != '\t')) +                || ((sc.state == SCE_A68K_IDENTIFIER) && (sc.ch < 0x80) && IsIdentifierChar(sc.ch))         // Identifier +                || ((sc.state == SCE_A68K_COMMENT_DOXYGEN) && (sc.ch < 0x80) && IsDoxygenChar(sc.ch))       // Doxygen keyword +                || ((sc.state == SCE_A68K_COMMENT_WORD) && (sc.ch < 0x80) && isalpha(sc.ch)))               // Comment current word +            { +                continue; +            } + +            // Check if some states terminate at the current char: +            // we must include this char in the current style context +            else if (((sc.state == SCE_A68K_STRING1)    && (sc.ch < 0x80) && (sc.ch == '\''))       // String single-quoted +                     || ((sc.state == SCE_A68K_STRING2) && (sc.ch < 0x80) && (sc.ch == '\"'))       // String double-quoted +                     || ((sc.state == SCE_A68K_LABEL)   && (sc.ch < 0x80) && (sc.ch == ':')))       // Label +            { +                sc.ForwardSetState(SCE_A68K_DEFAULT); +            } + +            // Check for special words or Doxygen keywords in comments +            else if (sc.state == SCE_A68K_COMMENT) +            { +                if (sc.ch == '\\') { +                    sc.SetState(SCE_A68K_COMMENT_DOXYGEN); +                } +                else if ((sc.ch < 0x80) && isalpha(sc.ch)) { +                    sc.SetState(SCE_A68K_COMMENT_WORD); +                } +                continue; +            } + +            // Check for special words in comment +            else if ((sc.state == SCE_A68K_COMMENT_WORD) && (sc.ch < 0x80) && !isalpha(sc.ch)) +            { +                sc.GetCurrent(Buffer, sizeof(Buffer)); +                if (commentSpecial.InList(Buffer)) { +                    sc.ChangeState(SCE_A68K_COMMENT_SPECIAL); +                } +                else { +                    sc.ChangeState(SCE_A68K_COMMENT); +                } +                sc.SetState(SCE_A68K_COMMENT); +                continue; +            } + +            // Check for Doxygen keywords +            else if ((sc.state == SCE_A68K_COMMENT_DOXYGEN) && (sc.ch < 0x80) && !IsDoxygenChar(sc.ch)) +            { +                sc.GetCurrentLowered(Buffer, sizeof(Buffer));                           // Buffer the string of the current context +                if (!doxygenKeyword.InList(Buffer)) { +                    sc.ChangeState(SCE_A68K_COMMENT); +                } +                sc.SetState(SCE_A68K_COMMENT); +                continue; +            } + +            // Check if we are in the case of a label which terminates without ':' +            // It should be a macro declaration, not a label +            else if ((sc.state == SCE_A68K_LABEL) && (sc.ch < 0x80) && ((sc.ch == ' ') || (sc.ch == '\t'))) +            { +                sc.ChangeState(SCE_A68K_MACRO_DECLARATION); +            } + +            // Check if we are at the end of an identifier +            // In this case, colourise it if was a keyword. +            else if ((sc.state == SCE_A68K_IDENTIFIER) && !IsIdentifierChar(sc.ch)) +            { +                sc.GetCurrentLowered(Buffer, sizeof(Buffer));                           // Buffer the string of the current context +                if (cpuInstruction.InList(Buffer)) {                                    // And check if it belongs to a keyword list +                    sc.ChangeState(SCE_A68K_CPUINSTRUCTION); +                } +                else if (extInstruction.InList(Buffer)) { +                    sc.ChangeState(SCE_A68K_EXTINSTRUCTION); +                } +                else if (registers.InList(Buffer)) { +                    sc.ChangeState(SCE_A68K_REGISTER); +                } +                else if (directive.InList(Buffer)) { +                    sc.ChangeState(SCE_A68K_DIRECTIVE); +                } +            } + +            // All special contexts are now handled.Come back to default style +            sc.SetState(SCE_A68K_DEFAULT); +        } + + +        /************************************************************ +        * +        *   Check if we must enter a new state +        * +        ************************************************************/ + +        // Label and macro identifiers start at the beginning of a line +        // We set both as a label, but if it wasn't one (no ':' at the end), +        // it will be changed as a macro identifier. +        if (sc.atLineStart && (sc.ch < 0x80) && IsIdentifierStart(sc.ch)) { +            sc.SetState(SCE_A68K_LABEL); +        } +        else if ((sc.ch < 0x80) && (sc.ch == ';')) {                            // Comment +            sc.SetState(SCE_A68K_COMMENT); +        } +        else if ((sc.ch < 0x80) && isdigit(sc.ch)) {                            // Decimal numbers haven't prefix +            sc.SetState(SCE_A68K_NUMBER_DEC); +        } +        else if ((sc.ch < 0x80) && (sc.ch == '%')) {                            // Binary numbers are prefixed with '%' +            sc.SetState(SCE_A68K_NUMBER_BIN); +        } +        else if ((sc.ch < 0x80) && (sc.ch == '$')) {                            // Hexadecimal numbers are prefixed with '$' +            sc.SetState(SCE_A68K_NUMBER_HEX); +        } +        else if ((sc.ch < 0x80) && (sc.ch == '\'')) {                           // String (single-quoted) +            sc.SetState(SCE_A68K_STRING1); +        } +        else if ((sc.ch < 0x80) && (sc.ch == '\"')) {                           // String (double-quoted) +            sc.SetState(SCE_A68K_STRING2); +        } +        else if ((sc.ch < 0x80) && (sc.ch == '\\') && (isdigit(sc.chNext))) {   // Replacement symbols in macro +            sc.SetState(SCE_A68K_MACRO_ARG); +        } +        else if ((sc.ch < 0x80) && IsIdentifierStart(sc.ch)) {                  // An identifier: constant, label, etc... +            sc.SetState(SCE_A68K_IDENTIFIER); +        } +        else { +            if (sc.ch < 0x80) { +                OpType = GetOperatorType(sc.ch, sc.chNext);                     // Check if current char is an operator +                if (OpType != NO_OPERATOR) { +                    sc.SetState(SCE_A68K_OPERATOR); +                    if (OpType == OPERATOR_2CHAR) {                             // Check if the operator is 2 bytes long +                        sc.ForwardSetState(SCE_A68K_OPERATOR);                  // (>> or <<) +                    } +                } +            } +        } +    }                                                                           // End of for() +    sc.Complete(); +} + + +// Names of the keyword lists + +static const char * const a68kWordListDesc[] = +{ +    "CPU instructions", +    "Registers", +    "Directives", +    "Extended instructions", +    "Comment special words", +    "Doxygen keywords", +    0 +}; + +LexerModule lmA68k(SCLEX_A68K, ColouriseA68kDoc, "a68k", 0, a68kWordListDesc); diff --git a/src/Catalogue.cxx b/src/Catalogue.cxx index a7ec50018..8b2e9b342 100644 --- a/src/Catalogue.cxx +++ b/src/Catalogue.cxx @@ -81,6 +81,7 @@ int Scintilla_LinkLexers() {  //++Autogenerated -- run src/LexGen.py to regenerate  //**\(\tLINK_LEXER(\*);\n\) +	LINK_LEXER(lmA68k);  	LINK_LEXER(lmAbaqus);  	LINK_LEXER(lmAda);  	LINK_LEXER(lmAns1); diff --git a/win32/scintilla.mak b/win32/scintilla.mak index c7d0f7441..e4a53a381 100644 --- a/win32/scintilla.mak +++ b/win32/scintilla.mak @@ -116,6 +116,7 @@ SOBJS=\  #++Autogenerated -- run src/LexGen.py to regenerate  #**LEXOBJS=\\\n\(\t$(DIR_O)\\\*.obj \\\n\)  LEXOBJS=\ +	$(DIR_O)\LexA68k.obj \  	$(DIR_O)\LexAbaqus.obj \  	$(DIR_O)\LexAda.obj \  	$(DIR_O)\LexAPDL.obj \ @@ -320,6 +321,8 @@ $(DIR_O)\KeyMap.obj: ../src/KeyMap.cxx ../include/Platform.h ../include/Scintill  #++Autogenerated -- run src/LexGen.py to regenerate  #**\n\($(DIR_O)\\\*.obj: ..\\lexers\\\*.cxx $(LEX_HEADERS)\n\n\) +$(DIR_O)\LexA68k.obj: ..\lexers\LexA68k.cxx $(LEX_HEADERS) +  $(DIR_O)\LexAbaqus.obj: ..\lexers\LexAbaqus.cxx $(LEX_HEADERS)  $(DIR_O)\LexAda.obj: ..\lexers\LexAda.cxx $(LEX_HEADERS) diff --git a/win32/scintilla_vc6.mak b/win32/scintilla_vc6.mak index 68175ad0c..fe33f3c50 100644 --- a/win32/scintilla_vc6.mak +++ b/win32/scintilla_vc6.mak @@ -118,6 +118,7 @@ SOBJS=\  #++Autogenerated -- run src/LexGen.py to regenerate  #**LEXOBJS=\\\n\(\t$(DIR_O)\\\*.obj \\\n\)  LEXOBJS=\ +	$(DIR_O)\LexA68k.obj \  	$(DIR_O)\LexAbaqus.obj \  	$(DIR_O)\LexAda.obj \  	$(DIR_O)\LexAPDL.obj \ @@ -322,6 +323,8 @@ $(DIR_O)\KeyMap.obj: ../src/KeyMap.cxx ../include/Platform.h ../include/Scintill  #++Autogenerated -- run src/LexGen.py to regenerate  #**\n\($(DIR_O)\\\*.obj: ..\\lexers\\\*.cxx $(LEX_HEADERS)\n\n\) +$(DIR_O)\LexA68k.obj: ..\lexers\LexA68k.cxx $(LEX_HEADERS) +  $(DIR_O)\LexAbaqus.obj: ..\lexers\LexAbaqus.cxx $(LEX_HEADERS)  $(DIR_O)\LexAda.obj: ..\lexers\LexAda.cxx $(LEX_HEADERS) | 
