diff options
author | nyamatongwe <devnull@localhost> | 2010-11-06 09:14:26 +1100 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2010-11-06 09:14:26 +1100 |
commit | 934758d6a6de8876c2dba9195cde71e21a60d1ba (patch) | |
tree | c06dd420c51db2919032a5f4ed8c114f370e93d7 | |
parent | c74941f39e03b2d36f70a9d6c35b693d9fc75926 (diff) | |
download | scintilla-mirror-934758d6a6de8876c2dba9195cde71e21a60d1ba.tar.gz |
Lexer for Motorola 68000 assembler.
-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) |