aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornyamatongwe <devnull@localhost>2010-11-06 09:14:26 +1100
committernyamatongwe <devnull@localhost>2010-11-06 09:14:26 +1100
commit934758d6a6de8876c2dba9195cde71e21a60d1ba (patch)
treec06dd420c51db2919032a5f4ed8c114f370e93d7
parentc74941f39e03b2d36f70a9d6c35b693d9fc75926 (diff)
downloadscintilla-mirror-934758d6a6de8876c2dba9195cde71e21a60d1ba.tar.gz
Lexer for Motorola 68000 assembler.
-rw-r--r--doc/ScintillaHistory.html1
-rw-r--r--include/SciLexer.h20
-rw-r--r--include/Scintilla.iface22
-rw-r--r--lexers/LexA68k.cxx319
-rw-r--r--src/Catalogue.cxx1
-rw-r--r--win32/scintilla.mak3
-rw-r--r--win32/scintilla_vc6.mak3
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 &registers = *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)