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"
26 using namespace Scintilla
;
30 static inline bool IsAWordChar(const int ch
) {
31 return (ch
< 0x80) && (isalnum(ch
) || ch
== ':' || ch
== '_');
34 inline bool isMMIXALOperator(char ch
) {
37 if (ch
== '+' || ch
== '-' || ch
== '|' || ch
== '^' ||
38 ch
== '*' || ch
== '/' || ch
== '/' ||
39 ch
== '%' || ch
== '<' || ch
== '>' || ch
== '&' ||
40 ch
== '~' || ch
== '$' ||
41 ch
== ',' || ch
== '(' || ch
== ')' ||
42 ch
== '[' || ch
== ']')
47 static void ColouriseMMIXALDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordlists
[],
50 WordList
&opcodes
= *keywordlists
[0];
51 WordList
&special_register
= *keywordlists
[1];
52 WordList
&predef_symbols
= *keywordlists
[2];
54 StyleContext
sc(startPos
, length
, initStyle
, styler
);
56 for (; sc
.More(); sc
.Forward())
58 // No EOL continuation
60 if (sc
.ch
== '@' && sc
.chNext
== 'i') {
61 sc
.SetState(SCE_MMIXAL_INCLUDE
);
63 sc
.SetState(SCE_MMIXAL_LEADWS
);
67 // Check if first non whitespace character in line is alphanumeric
68 if (sc
.state
== SCE_MMIXAL_LEADWS
&& !isspace(sc
.ch
)) { // LEADWS
69 if(!IsAWordChar(sc
.ch
)) {
70 sc
.SetState(SCE_MMIXAL_COMMENT
);
73 sc
.SetState(SCE_MMIXAL_LABEL
);
75 sc
.SetState(SCE_MMIXAL_OPCODE_PRE
);
80 // Determine if the current state should terminate.
81 if (sc
.state
== SCE_MMIXAL_OPERATOR
) { // OPERATOR
82 sc
.SetState(SCE_MMIXAL_OPERANDS
);
83 } else if (sc
.state
== SCE_MMIXAL_NUMBER
) { // NUMBER
84 if (!isdigit(sc
.ch
)) {
85 if (IsAWordChar(sc
.ch
)) {
87 sc
.GetCurrent(s
, sizeof(s
));
88 sc
.ChangeState(SCE_MMIXAL_REF
);
89 sc
.SetState(SCE_MMIXAL_REF
);
91 sc
.SetState(SCE_MMIXAL_OPERANDS
);
94 } else if (sc
.state
== SCE_MMIXAL_LABEL
) { // LABEL
95 if (!IsAWordChar(sc
.ch
) ) {
96 sc
.SetState(SCE_MMIXAL_OPCODE_PRE
);
98 } else if (sc
.state
== SCE_MMIXAL_REF
) { // REF
99 if (!IsAWordChar(sc
.ch
) ) {
101 sc
.GetCurrent(s
, sizeof(s
));
102 if (*s
== ':') { // ignore base prefix for match
103 for (size_t i
= 0; i
!= sizeof(s
); ++i
) {
107 if (special_register
.InList(s
)) {
108 sc
.ChangeState(SCE_MMIXAL_REGISTER
);
109 } else if (predef_symbols
.InList(s
)) {
110 sc
.ChangeState(SCE_MMIXAL_SYMBOL
);
112 sc
.SetState(SCE_MMIXAL_OPERANDS
);
114 } else if (sc
.state
== SCE_MMIXAL_OPCODE_PRE
) { // OPCODE_PRE
115 if (!isspace(sc
.ch
)) {
116 sc
.SetState(SCE_MMIXAL_OPCODE
);
118 } else if (sc
.state
== SCE_MMIXAL_OPCODE
) { // OPCODE
119 if (!IsAWordChar(sc
.ch
) ) {
121 sc
.GetCurrent(s
, sizeof(s
));
122 if (opcodes
.InList(s
)) {
123 sc
.ChangeState(SCE_MMIXAL_OPCODE_VALID
);
125 sc
.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN
);
127 sc
.SetState(SCE_MMIXAL_OPCODE_POST
);
129 } else if (sc
.state
== SCE_MMIXAL_STRING
) { // STRING
131 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
132 } else if (sc
.atLineEnd
) {
133 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
135 } else if (sc
.state
== SCE_MMIXAL_CHAR
) { // CHAR
137 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
138 } else if (sc
.atLineEnd
) {
139 sc
.ForwardSetState(SCE_MMIXAL_OPERANDS
);
141 } else if (sc
.state
== SCE_MMIXAL_REGISTER
) { // REGISTER
142 if (!isdigit(sc
.ch
)) {
143 sc
.SetState(SCE_MMIXAL_OPERANDS
);
145 } else if (sc
.state
== SCE_MMIXAL_HEX
) { // HEX
146 if (!isxdigit(sc
.ch
)) {
147 sc
.SetState(SCE_MMIXAL_OPERANDS
);
151 // Determine if a new state should be entered.
152 if (sc
.state
== SCE_MMIXAL_OPCODE_POST
|| // OPCODE_POST
153 sc
.state
== SCE_MMIXAL_OPERANDS
) { // OPERANDS
154 if (sc
.state
== SCE_MMIXAL_OPERANDS
&& isspace(sc
.ch
)) {
156 sc
.SetState(SCE_MMIXAL_COMMENT
);
158 } else if (isdigit(sc
.ch
)) {
159 sc
.SetState(SCE_MMIXAL_NUMBER
);
160 } else if (IsAWordChar(sc
.ch
) || sc
.Match('@')) {
161 sc
.SetState(SCE_MMIXAL_REF
);
162 } else if (sc
.Match('\"')) {
163 sc
.SetState(SCE_MMIXAL_STRING
);
164 } else if (sc
.Match('\'')) {
165 sc
.SetState(SCE_MMIXAL_CHAR
);
166 } else if (sc
.Match('$')) {
167 sc
.SetState(SCE_MMIXAL_REGISTER
);
168 } else if (sc
.Match('#')) {
169 sc
.SetState(SCE_MMIXAL_HEX
);
170 } else if (isMMIXALOperator(static_cast<char>(sc
.ch
))) {
171 sc
.SetState(SCE_MMIXAL_OPERATOR
);
178 static const char * const MMIXALWordListDesc
[] = {
181 "Predefined Symbols",
185 LexerModule
lmMMIXAL(SCLEX_MMIXAL
, ColouriseMMIXALDoc
, "mmixal", 0, MMIXALWordListDesc
);