1 // Scintilla source code edit control
3 /** @file LexMMIXAL.cxx
4 ** Lexer for MMIX Assembler Language.
5 ** Written by Christoph Hösler <christoph.hoesler@student.uni-tuebingen.de>
6 ** For information about MMIX visit http://www-cs-faculty.stanford.edu/~knuth/mmix.html
8 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
9 // The License.txt file describes the conditions under which this software may be distributed.
19 #include "Scintilla.h"
23 #include "LexAccessor.h"
25 #include "StyleContext.h"
26 #include "CharacterSet.h"
27 #include "LexerModule.h"
29 using namespace Scintilla
;
32 static inline bool IsAWordChar(const int ch
) {
33 return (ch
< 0x80) && (isalnum(ch
) || ch
== ':' || ch
== '_');
36 inline bool isMMIXALOperator(char ch
) {
37 if (IsASCII(ch
) && isalnum(ch
))
39 if (ch
== '+' || ch
== '-' || ch
== '|' || ch
== '^' ||
40 ch
== '*' || ch
== '/' ||
41 ch
== '%' || ch
== '<' || ch
== '>' || ch
== '&' ||
42 ch
== '~' || ch
== '$' ||
43 ch
== ',' || ch
== '(' || ch
== ')' ||
44 ch
== '[' || ch
== ']')
49 static void ColouriseMMIXALDoc(Sci_PositionU startPos
, Sci_Position length
, int initStyle
, WordList
*keywordlists
[],
52 WordList
&opcodes
= *keywordlists
[0];
53 WordList
&special_register
= *keywordlists
[1];
54 WordList
&predef_symbols
= *keywordlists
[2];
56 StyleContext
sc(startPos
, length
, initStyle
, styler
);
58 for (; sc
.More(); sc
.Forward())
60 // No EOL continuation
62 if (sc
.ch
== '@' && sc
.chNext
== 'i') {
63 sc
.SetState(SCE_MMIXAL_INCLUDE
);
65 sc
.SetState(SCE_MMIXAL_LEADWS
);
69 // Check if first non whitespace character in line is alphanumeric
70 if (sc
.state
== SCE_MMIXAL_LEADWS
&& !isspace(sc
.ch
)) { // LEADWS
71 if(!IsAWordChar(sc
.ch
)) {
72 sc
.SetState(SCE_MMIXAL_COMMENT
);
75 sc
.SetState(SCE_MMIXAL_LABEL
);
77 sc
.SetState(SCE_MMIXAL_OPCODE_PRE
);
82 // Determine if the current state should terminate.
83 if (sc
.state
== SCE_MMIXAL_OPERATOR
) { // OPERATOR
84 sc
.SetState(SCE_MMIXAL_OPERANDS
);
85 } else if (sc
.state
== SCE_MMIXAL_NUMBER
) { // NUMBER
86 if (!isdigit(sc
.ch
)) {
87 if (IsAWordChar(sc
.ch
)) {
89 sc
.GetCurrent(s
, sizeof(s
));
90 sc
.ChangeState(SCE_MMIXAL_REF
);
91 sc
.SetState(SCE_MMIXAL_REF
);
93 sc
.SetState(SCE_MMIXAL_OPERANDS
);
96 } else if (sc
.state
== SCE_MMIXAL_LABEL
) { // LABEL
97 if (!IsAWordChar(sc
.ch
) ) {
98 sc
.SetState(SCE_MMIXAL_OPCODE_PRE
);
100 } else if (sc
.state
== SCE_MMIXAL_REF
) { // REF
101 if (!IsAWordChar(sc
.ch
) ) {
103 sc
.GetCurrent(s
, sizeof(s
));
104 if (*s
== ':') { // ignore base prefix for match
105 for (size_t i
= 0; i
!= sizeof(s
); ++i
) {
109 if (special_register
.InList(s
)) {
110 sc
.ChangeState(SCE_MMIXAL_REGISTER
);
111 } else if (predef_symbols
.InList(s
)) {
112 sc
.ChangeState(SCE_MMIXAL_SYMBOL
);
114 sc
.SetState(SCE_MMIXAL_OPERANDS
);
116 } else if (sc
.state
== SCE_MMIXAL_OPCODE_PRE
) { // OPCODE_PRE
117 if (!isspace(sc
.ch
)) {
118 sc
.SetState(SCE_MMIXAL_OPCODE
);
120 } else if (sc
.state
== SCE_MMIXAL_OPCODE
) { // OPCODE
121 if (!IsAWordChar(sc
.ch
) ) {
123 sc
.GetCurrent(s
, sizeof(s
));
124 if (opcodes
.InList(s
)) {
125 sc
.ChangeState(SCE_MMIXAL_OPCODE_VALID
);
127 sc
.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN
);
129 sc
.SetState(SCE_MMIXAL_OPCODE_POST
);
131 } else if (sc
.state
== SCE_MMIXAL_STRING
) { // STRING
133 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
134 } else if (sc
.atLineEnd
) {
135 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
137 } else if (sc
.state
== SCE_MMIXAL_CHAR
) { // CHAR
139 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
140 } else if (sc
.atLineEnd
) {
141 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
143 } else if (sc
.state
== SCE_MMIXAL_REGISTER
) { // REGISTER
144 if (!isdigit(sc
.ch
)) {
145 sc
.SetState(SCE_MMIXAL_OPERANDS
);
147 } else if (sc
.state
== SCE_MMIXAL_HEX
) { // HEX
148 if (!isxdigit(sc
.ch
)) {
149 sc
.SetState(SCE_MMIXAL_OPERANDS
);
153 // Determine if a new state should be entered.
154 if (sc
.state
== SCE_MMIXAL_OPCODE_POST
|| // OPCODE_POST
155 sc
.state
== SCE_MMIXAL_OPERANDS
) { // OPERANDS
156 if (sc
.state
== SCE_MMIXAL_OPERANDS
&& isspace(sc
.ch
)) {
158 sc
.SetState(SCE_MMIXAL_COMMENT
);
160 } else if (isdigit(sc
.ch
)) {
161 sc
.SetState(SCE_MMIXAL_NUMBER
);
162 } else if (IsAWordChar(sc
.ch
) || sc
.Match('@')) {
163 sc
.SetState(SCE_MMIXAL_REF
);
164 } else if (sc
.Match('\"')) {
165 sc
.SetState(SCE_MMIXAL_STRING
);
166 } else if (sc
.Match('\'')) {
167 sc
.SetState(SCE_MMIXAL_CHAR
);
168 } else if (sc
.Match('$')) {
169 sc
.SetState(SCE_MMIXAL_REGISTER
);
170 } else if (sc
.Match('#')) {
171 sc
.SetState(SCE_MMIXAL_HEX
);
172 } else if (isMMIXALOperator(static_cast<char>(sc
.ch
))) {
173 sc
.SetState(SCE_MMIXAL_OPERATOR
);
180 static const char * const MMIXALWordListDesc
[] = {
183 "Predefined Symbols",
187 LexerModule
lmMMIXAL(SCLEX_MMIXAL
, ColouriseMMIXALDoc
, "mmixal", 0, MMIXALWordListDesc
);