1 // Scintilla source code edit control
2 /** @file LexMMIXAL.cxx
3 ** Lexer for MMIX Assembler Language.
4 ** Written by Christoph Hösler <christoph.hoesler@student.uni-tuebingen.de>
5 ** For information about MMIX visit http://www-cs-faculty.stanford.edu/~knuth/mmix.html
7 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
8 // The License.txt file describes the conditions under which this software may be distributed.
18 #include "Scintilla.h"
22 #include "LexAccessor.h"
24 #include "StyleContext.h"
25 #include "CharacterSet.h"
26 #include "LexerModule.h"
29 using namespace Scintilla
;
33 static inline bool IsAWordChar(const int ch
) {
34 return (ch
< 0x80) && (isalnum(ch
) || ch
== ':' || ch
== '_');
37 inline bool isMMIXALOperator(char ch
) {
38 if (isascii(ch
) && isalnum(ch
))
40 if (ch
== '+' || ch
== '-' || ch
== '|' || ch
== '^' ||
41 ch
== '*' || ch
== '/' ||
42 ch
== '%' || ch
== '<' || ch
== '>' || ch
== '&' ||
43 ch
== '~' || ch
== '$' ||
44 ch
== ',' || ch
== '(' || ch
== ')' ||
45 ch
== '[' || ch
== ']')
50 static void ColouriseMMIXALDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
53 WordList
&opcodes
= *keywordlists
[0];
54 WordList
&special_register
= *keywordlists
[1];
55 WordList
&predef_symbols
= *keywordlists
[2];
57 StyleContext
sc(startPos
, length
, initStyle
, styler
);
59 for (; sc
.More(); sc
.Forward())
61 // No EOL continuation
63 if (sc
.ch
== '@' && sc
.chNext
== 'i') {
64 sc
.SetState(SCE_MMIXAL_INCLUDE
);
66 sc
.SetState(SCE_MMIXAL_LEADWS
);
70 // Check if first non whitespace character in line is alphanumeric
71 if (sc
.state
== SCE_MMIXAL_LEADWS
&& !isspace(sc
.ch
)) { // LEADWS
72 if(!IsAWordChar(sc
.ch
)) {
73 sc
.SetState(SCE_MMIXAL_COMMENT
);
76 sc
.SetState(SCE_MMIXAL_LABEL
);
78 sc
.SetState(SCE_MMIXAL_OPCODE_PRE
);
83 // Determine if the current state should terminate.
84 if (sc
.state
== SCE_MMIXAL_OPERATOR
) { // OPERATOR
85 sc
.SetState(SCE_MMIXAL_OPERANDS
);
86 } else if (sc
.state
== SCE_MMIXAL_NUMBER
) { // NUMBER
87 if (!isdigit(sc
.ch
)) {
88 if (IsAWordChar(sc
.ch
)) {
90 sc
.GetCurrent(s
, sizeof(s
));
91 sc
.ChangeState(SCE_MMIXAL_REF
);
92 sc
.SetState(SCE_MMIXAL_REF
);
94 sc
.SetState(SCE_MMIXAL_OPERANDS
);
97 } else if (sc
.state
== SCE_MMIXAL_LABEL
) { // LABEL
98 if (!IsAWordChar(sc
.ch
) ) {
99 sc
.SetState(SCE_MMIXAL_OPCODE_PRE
);
101 } else if (sc
.state
== SCE_MMIXAL_REF
) { // REF
102 if (!IsAWordChar(sc
.ch
) ) {
104 sc
.GetCurrent(s
, sizeof(s
));
105 if (*s
== ':') { // ignore base prefix for match
106 for (size_t i
= 0; i
!= sizeof(s
); ++i
) {
110 if (special_register
.InList(s
)) {
111 sc
.ChangeState(SCE_MMIXAL_REGISTER
);
112 } else if (predef_symbols
.InList(s
)) {
113 sc
.ChangeState(SCE_MMIXAL_SYMBOL
);
115 sc
.SetState(SCE_MMIXAL_OPERANDS
);
117 } else if (sc
.state
== SCE_MMIXAL_OPCODE_PRE
) { // OPCODE_PRE
118 if (!isspace(sc
.ch
)) {
119 sc
.SetState(SCE_MMIXAL_OPCODE
);
121 } else if (sc
.state
== SCE_MMIXAL_OPCODE
) { // OPCODE
122 if (!IsAWordChar(sc
.ch
) ) {
124 sc
.GetCurrent(s
, sizeof(s
));
125 if (opcodes
.InList(s
)) {
126 sc
.ChangeState(SCE_MMIXAL_OPCODE_VALID
);
128 sc
.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN
);
130 sc
.SetState(SCE_MMIXAL_OPCODE_POST
);
132 } else if (sc
.state
== SCE_MMIXAL_STRING
) { // STRING
134 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
135 } else if (sc
.atLineEnd
) {
136 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
138 } else if (sc
.state
== SCE_MMIXAL_CHAR
) { // CHAR
140 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
141 } else if (sc
.atLineEnd
) {
142 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
144 } else if (sc
.state
== SCE_MMIXAL_REGISTER
) { // REGISTER
145 if (!isdigit(sc
.ch
)) {
146 sc
.SetState(SCE_MMIXAL_OPERANDS
);
148 } else if (sc
.state
== SCE_MMIXAL_HEX
) { // HEX
149 if (!isxdigit(sc
.ch
)) {
150 sc
.SetState(SCE_MMIXAL_OPERANDS
);
154 // Determine if a new state should be entered.
155 if (sc
.state
== SCE_MMIXAL_OPCODE_POST
|| // OPCODE_POST
156 sc
.state
== SCE_MMIXAL_OPERANDS
) { // OPERANDS
157 if (sc
.state
== SCE_MMIXAL_OPERANDS
&& isspace(sc
.ch
)) {
159 sc
.SetState(SCE_MMIXAL_COMMENT
);
161 } else if (isdigit(sc
.ch
)) {
162 sc
.SetState(SCE_MMIXAL_NUMBER
);
163 } else if (IsAWordChar(sc
.ch
) || sc
.Match('@')) {
164 sc
.SetState(SCE_MMIXAL_REF
);
165 } else if (sc
.Match('\"')) {
166 sc
.SetState(SCE_MMIXAL_STRING
);
167 } else if (sc
.Match('\'')) {
168 sc
.SetState(SCE_MMIXAL_CHAR
);
169 } else if (sc
.Match('$')) {
170 sc
.SetState(SCE_MMIXAL_REGISTER
);
171 } else if (sc
.Match('#')) {
172 sc
.SetState(SCE_MMIXAL_HEX
);
173 } else if (isMMIXALOperator(static_cast<char>(sc
.ch
))) {
174 sc
.SetState(SCE_MMIXAL_OPERATOR
);
181 static const char * const MMIXALWordListDesc
[] = {
184 "Predefined Symbols",
188 LexerModule
lmMMIXAL(SCLEX_MMIXAL
, ColouriseMMIXALDoc
, "mmixal", 0, MMIXALWordListDesc
);