]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/LexMMIXAL.cxx
Patch #1106564, corrects possible 100% CPU load condition.
[wxWidgets.git] / contrib / 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
26
27 static inline bool IsAWordChar(const int ch) {
28 return (ch < 0x80) && (isalnum(ch) || ch == ':' || ch == '_');
29 }
30
31 inline bool isMMIXALOperator(char ch) {
32 if (isalnum(ch))
33 return false;
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 == ']')
40 return true;
41 return false;
42 }
43
44 static void ColouriseMMIXALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
45 Accessor &styler) {
46
47 WordList &opcodes = *keywordlists[0];
48 WordList &special_register = *keywordlists[1];
49 WordList &predef_symbols = *keywordlists[2];
50
51 StyleContext sc(startPos, length, initStyle, styler);
52
53 for (; sc.More(); sc.Forward())
54 {
55 // No EOL continuation
56 if (sc.atLineStart) {
57 if (sc.ch == '@' && sc.chNext == 'i') {
58 sc.SetState(SCE_MMIXAL_INCLUDE);
59 } else {
60 sc.SetState(SCE_MMIXAL_LEADWS);
61 }
62 }
63
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);
68 } else {
69 if(sc.atLineStart) {
70 sc.SetState(SCE_MMIXAL_LABEL);
71 } else {
72 sc.SetState(SCE_MMIXAL_OPCODE_PRE);
73 }
74 }
75 }
76
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)) {
83 char s[100];
84 sc.GetCurrent(s, sizeof(s));
85 sc.ChangeState(SCE_MMIXAL_REF);
86 sc.SetState(SCE_MMIXAL_REF);
87 } else {
88 sc.SetState(SCE_MMIXAL_OPERANDS);
89 }
90 }
91 } else if (sc.state == SCE_MMIXAL_LABEL) { // LABEL
92 if (!IsAWordChar(sc.ch) ) {
93 sc.SetState(SCE_MMIXAL_OPCODE_PRE);
94 }
95 } else if (sc.state == SCE_MMIXAL_REF) { // REF
96 if (!IsAWordChar(sc.ch) ) {
97 char s[100];
98 sc.GetCurrent(s, sizeof(s));
99 if (*s == ':') { // ignore base prefix for match
100 for (size_t i = 0; i != sizeof(s); ++i) {
101 *(s+i) = *(s+i+1);
102 }
103 }
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);
108 }
109 sc.SetState(SCE_MMIXAL_OPERANDS);
110 }
111 } else if (sc.state == SCE_MMIXAL_OPCODE_PRE) { // OPCODE_PRE
112 if (!isspace(sc.ch)) {
113 sc.SetState(SCE_MMIXAL_OPCODE);
114 }
115 } else if (sc.state == SCE_MMIXAL_OPCODE) { // OPCODE
116 if (!IsAWordChar(sc.ch) ) {
117 char s[100];
118 sc.GetCurrent(s, sizeof(s));
119 if (opcodes.InList(s)) {
120 sc.ChangeState(SCE_MMIXAL_OPCODE_VALID);
121 } else {
122 sc.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN);
123 }
124 sc.SetState(SCE_MMIXAL_OPCODE_POST);
125 }
126 } else if (sc.state == SCE_MMIXAL_STRING) { // STRING
127 if (sc.ch == '\"') {
128 sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
129 } else if (sc.atLineEnd) {
130 sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
131 }
132 } else if (sc.state == SCE_MMIXAL_CHAR) { // CHAR
133 if (sc.ch == '\'') {
134 sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
135 } else if (sc.atLineEnd) {
136 sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
137 }
138 } else if (sc.state == SCE_MMIXAL_REGISTER) { // REGISTER
139 if (!isdigit(sc.ch)) {
140 sc.SetState(SCE_MMIXAL_OPERANDS);
141 }
142 } else if (sc.state == SCE_MMIXAL_HEX) { // HEX
143 if (!isxdigit(sc.ch)) {
144 sc.SetState(SCE_MMIXAL_OPERANDS);
145 }
146 }
147
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)) {
152 if (!sc.atLineEnd) {
153 sc.SetState(SCE_MMIXAL_COMMENT);
154 }
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);
169 }
170 }
171 }
172 sc.Complete();
173 }
174
175 static const char * const MMIXALWordListDesc[] = {
176 "Operation Codes",
177 "Special Register",
178 "Predefined Symbols",
179 0
180 };
181
182 LexerModule lmMMIXAL(SCLEX_MMIXAL, ColouriseMMIXALDoc, "mmixal", 0, MMIXALWordListDesc);
183