]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexMMIXAL.cxx
a00f35ca038885936352a303aea85b64669ae426
[wxWidgets.git] / src / stc / scintilla / src / LexMMIXAL.cxx
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
6 **/
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.
9
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <stdio.h>
14 #include <stdarg.h>
15
16 #include "Platform.h"
17
18 #include "PropSet.h"
19 #include "Accessor.h"
20 #include "StyleContext.h"
21 #include "KeyWords.h"
22 #include "Scintilla.h"
23 #include "SciLexer.h"
24
25 #ifdef SCI_NAMESPACE
26 using namespace Scintilla;
27 #endif
28
29
30 static inline bool IsAWordChar(const int ch) {
31 return (ch < 0x80) && (isalnum(ch) || ch == ':' || ch == '_');
32 }
33
34 inline bool isMMIXALOperator(char ch) {
35 if (isalnum(ch))
36 return false;
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 == ']')
43 return true;
44 return false;
45 }
46
47 static void ColouriseMMIXALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
48 Accessor &styler) {
49
50 WordList &opcodes = *keywordlists[0];
51 WordList &special_register = *keywordlists[1];
52 WordList &predef_symbols = *keywordlists[2];
53
54 StyleContext sc(startPos, length, initStyle, styler);
55
56 for (; sc.More(); sc.Forward())
57 {
58 // No EOL continuation
59 if (sc.atLineStart) {
60 if (sc.ch == '@' && sc.chNext == 'i') {
61 sc.SetState(SCE_MMIXAL_INCLUDE);
62 } else {
63 sc.SetState(SCE_MMIXAL_LEADWS);
64 }
65 }
66
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);
71 } else {
72 if(sc.atLineStart) {
73 sc.SetState(SCE_MMIXAL_LABEL);
74 } else {
75 sc.SetState(SCE_MMIXAL_OPCODE_PRE);
76 }
77 }
78 }
79
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)) {
86 char s[100];
87 sc.GetCurrent(s, sizeof(s));
88 sc.ChangeState(SCE_MMIXAL_REF);
89 sc.SetState(SCE_MMIXAL_REF);
90 } else {
91 sc.SetState(SCE_MMIXAL_OPERANDS);
92 }
93 }
94 } else if (sc.state == SCE_MMIXAL_LABEL) { // LABEL
95 if (!IsAWordChar(sc.ch) ) {
96 sc.SetState(SCE_MMIXAL_OPCODE_PRE);
97 }
98 } else if (sc.state == SCE_MMIXAL_REF) { // REF
99 if (!IsAWordChar(sc.ch) ) {
100 char s[100];
101 sc.GetCurrent(s, sizeof(s));
102 if (*s == ':') { // ignore base prefix for match
103 for (size_t i = 0; i != sizeof(s); ++i) {
104 *(s+i) = *(s+i+1);
105 }
106 }
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);
111 }
112 sc.SetState(SCE_MMIXAL_OPERANDS);
113 }
114 } else if (sc.state == SCE_MMIXAL_OPCODE_PRE) { // OPCODE_PRE
115 if (!isspace(sc.ch)) {
116 sc.SetState(SCE_MMIXAL_OPCODE);
117 }
118 } else if (sc.state == SCE_MMIXAL_OPCODE) { // OPCODE
119 if (!IsAWordChar(sc.ch) ) {
120 char s[100];
121 sc.GetCurrent(s, sizeof(s));
122 if (opcodes.InList(s)) {
123 sc.ChangeState(SCE_MMIXAL_OPCODE_VALID);
124 } else {
125 sc.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN);
126 }
127 sc.SetState(SCE_MMIXAL_OPCODE_POST);
128 }
129 } else if (sc.state == SCE_MMIXAL_STRING) { // STRING
130 if (sc.ch == '\"') {
131 sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
132 } else if (sc.atLineEnd) {
133 sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
134 }
135 } else if (sc.state == SCE_MMIXAL_CHAR) { // CHAR
136 if (sc.ch == '\'') {
137 sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
138 } else if (sc.atLineEnd) {
139 sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
140 }
141 } else if (sc.state == SCE_MMIXAL_REGISTER) { // REGISTER
142 if (!isdigit(sc.ch)) {
143 sc.SetState(SCE_MMIXAL_OPERANDS);
144 }
145 } else if (sc.state == SCE_MMIXAL_HEX) { // HEX
146 if (!isxdigit(sc.ch)) {
147 sc.SetState(SCE_MMIXAL_OPERANDS);
148 }
149 }
150
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)) {
155 if (!sc.atLineEnd) {
156 sc.SetState(SCE_MMIXAL_COMMENT);
157 }
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);
172 }
173 }
174 }
175 sc.Complete();
176 }
177
178 static const char * const MMIXALWordListDesc[] = {
179 "Operation Codes",
180 "Special Register",
181 "Predefined Symbols",
182 0
183 };
184
185 LexerModule lmMMIXAL(SCLEX_MMIXAL, ColouriseMMIXALDoc, "mmixal", 0, MMIXALWordListDesc);
186