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.
20 #include "StyleContext.h"
22 #include "Scintilla.h"
27 static inline bool IsAWordChar(const int ch
) {
28 return (ch
< 0x80) && (isalnum(ch
) || ch
== ':' || ch
== '_');
31 inline bool isMMIXALOperator(char ch
) {
34 if (ch
== '+' || ch
== '-' || ch
== '|' || ch
== '^' ||
35 ch
== '*' || ch
== '/' || ch
== '/' ||
36 ch
== '%' || ch
== '<' || ch
== '>' || ch
== '&' ||
37 ch
== '~' || ch
== '$' ||
38 ch
== ',' || ch
== '(' || ch
== ')' ||
39 ch
== '[' || ch
== ']')
44 static void ColouriseMMIXALDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
47 WordList
&opcodes
= *keywordlists
[0];
48 WordList
&special_register
= *keywordlists
[1];
49 WordList
&predef_symbols
= *keywordlists
[2];
51 StyleContext
sc(startPos
, length
, initStyle
, styler
);
53 for (; sc
.More(); sc
.Forward())
55 // No EOL continuation
57 if (sc
.ch
== '@' && sc
.chNext
== 'i') {
58 sc
.SetState(SCE_MMIXAL_INCLUDE
);
60 sc
.SetState(SCE_MMIXAL_LEADWS
);
64 // Check if first non whitespace character in line is alphanumeric
65 if (sc
.state
== SCE_MMIXAL_LEADWS
&& !isspace(sc
.ch
)) { // LEADWS
66 if(!IsAWordChar(sc
.ch
)) {
67 sc
.SetState(SCE_MMIXAL_COMMENT
);
70 sc
.SetState(SCE_MMIXAL_LABEL
);
72 sc
.SetState(SCE_MMIXAL_OPCODE_PRE
);
77 // Determine if the current state should terminate.
78 if (sc
.state
== SCE_MMIXAL_OPERATOR
) { // OPERATOR
79 sc
.SetState(SCE_MMIXAL_OPERANDS
);
80 } else if (sc
.state
== SCE_MMIXAL_NUMBER
) { // NUMBER
81 if (!isdigit(sc
.ch
)) {
82 if (IsAWordChar(sc
.ch
)) {
84 sc
.GetCurrent(s
, sizeof(s
));
85 sc
.ChangeState(SCE_MMIXAL_REF
);
86 sc
.SetState(SCE_MMIXAL_REF
);
88 sc
.SetState(SCE_MMIXAL_OPERANDS
);
91 } else if (sc
.state
== SCE_MMIXAL_LABEL
) { // LABEL
92 if (!IsAWordChar(sc
.ch
) ) {
93 sc
.SetState(SCE_MMIXAL_OPCODE_PRE
);
95 } else if (sc
.state
== SCE_MMIXAL_REF
) { // REF
96 if (!IsAWordChar(sc
.ch
) ) {
98 sc
.GetCurrent(s
, sizeof(s
));
99 if (*s
== ':') { // ignore base prefix for match
100 for (size_t i
= 0; i
!= sizeof(s
); ++i
) {
104 if (special_register
.InList(s
)) {
105 sc
.ChangeState(SCE_MMIXAL_REGISTER
);
106 } else if (predef_symbols
.InList(s
)) {
107 sc
.ChangeState(SCE_MMIXAL_SYMBOL
);
109 sc
.SetState(SCE_MMIXAL_OPERANDS
);
111 } else if (sc
.state
== SCE_MMIXAL_OPCODE_PRE
) { // OPCODE_PRE
112 if (!isspace(sc
.ch
)) {
113 sc
.SetState(SCE_MMIXAL_OPCODE
);
115 } else if (sc
.state
== SCE_MMIXAL_OPCODE
) { // OPCODE
116 if (!IsAWordChar(sc
.ch
) ) {
118 sc
.GetCurrent(s
, sizeof(s
));
119 if (opcodes
.InList(s
)) {
120 sc
.ChangeState(SCE_MMIXAL_OPCODE_VALID
);
122 sc
.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN
);
124 sc
.SetState(SCE_MMIXAL_OPCODE_POST
);
126 } else if (sc
.state
== SCE_MMIXAL_STRING
) { // STRING
128 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
129 } else if (sc
.atLineEnd
) {
130 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
132 } else if (sc
.state
== SCE_MMIXAL_CHAR
) { // CHAR
134 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
135 } else if (sc
.atLineEnd
) {
136 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
138 } else if (sc
.state
== SCE_MMIXAL_REGISTER
) { // REGISTER
139 if (!isdigit(sc
.ch
)) {
140 sc
.SetState(SCE_MMIXAL_OPERANDS
);
142 } else if (sc
.state
== SCE_MMIXAL_HEX
) { // HEX
143 if (!isxdigit(sc
.ch
)) {
144 sc
.SetState(SCE_MMIXAL_OPERANDS
);
148 // Determine if a new state should be entered.
149 if (sc
.state
== SCE_MMIXAL_OPCODE_POST
|| // OPCODE_POST
150 sc
.state
== SCE_MMIXAL_OPERANDS
) { // OPERANDS
151 if (sc
.state
== SCE_MMIXAL_OPERANDS
&& isspace(sc
.ch
)) {
153 sc
.SetState(SCE_MMIXAL_COMMENT
);
155 } else if (isdigit(sc
.ch
)) {
156 sc
.SetState(SCE_MMIXAL_NUMBER
);
157 } else if (IsAWordChar(sc
.ch
) || sc
.Match('@')) {
158 sc
.SetState(SCE_MMIXAL_REF
);
159 } else if (sc
.Match('\"')) {
160 sc
.SetState(SCE_MMIXAL_STRING
);
161 } else if (sc
.Match('\'')) {
162 sc
.SetState(SCE_MMIXAL_CHAR
);
163 } else if (sc
.Match('$')) {
164 sc
.SetState(SCE_MMIXAL_REGISTER
);
165 } else if (sc
.Match('#')) {
166 sc
.SetState(SCE_MMIXAL_HEX
);
167 } else if (isMMIXALOperator(static_cast<char>(sc
.ch
))) {
168 sc
.SetState(SCE_MMIXAL_OPERATOR
);
175 static const char * const MMIXALWordListDesc
[] = {
178 "Predefined Symbols",
182 LexerModule
lmMMIXAL(SCLEX_MMIXAL
, ColouriseMMIXALDoc
, "mmixal", 0, MMIXALWordListDesc
);