Scintilla 4.0.3
[TortoiseGit.git] / ext / scintilla / lexers / LexMMIXAL.cxx
blobd65dafc259fdd1c7091eb129cc2b37a6cac9e31c
1 // Scintilla source code edit control
2 // Encoding: UTF-8
3 /** @file LexMMIXAL.cxx
4 ** Lexer for MMIX Assembler Language.
5 ** Written by Christoph Hösler <christoph.hoesler@student.uni-tuebingen.de>
6 ** For information about MMIX visit http://www-cs-faculty.stanford.edu/~knuth/mmix.html
7 **/
8 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
9 // The License.txt file describes the conditions under which this software may be distributed.
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <stdarg.h>
15 #include <assert.h>
16 #include <ctype.h>
18 #include "ILexer.h"
19 #include "Scintilla.h"
20 #include "SciLexer.h"
22 #include "WordList.h"
23 #include "LexAccessor.h"
24 #include "Accessor.h"
25 #include "StyleContext.h"
26 #include "CharacterSet.h"
27 #include "LexerModule.h"
29 using namespace Scintilla;
32 static inline bool IsAWordChar(const int ch) {
33 return (ch < 0x80) && (isalnum(ch) || ch == ':' || ch == '_');
36 inline bool isMMIXALOperator(char ch) {
37 if (IsASCII(ch) && isalnum(ch))
38 return false;
39 if (ch == '+' || ch == '-' || ch == '|' || ch == '^' ||
40 ch == '*' || ch == '/' ||
41 ch == '%' || ch == '<' || ch == '>' || ch == '&' ||
42 ch == '~' || ch == '$' ||
43 ch == ',' || ch == '(' || ch == ')' ||
44 ch == '[' || ch == ']')
45 return true;
46 return false;
49 static void ColouriseMMIXALDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
50 Accessor &styler) {
52 WordList &opcodes = *keywordlists[0];
53 WordList &special_register = *keywordlists[1];
54 WordList &predef_symbols = *keywordlists[2];
56 StyleContext sc(startPos, length, initStyle, styler);
58 for (; sc.More(); sc.Forward())
60 // No EOL continuation
61 if (sc.atLineStart) {
62 if (sc.ch == '@' && sc.chNext == 'i') {
63 sc.SetState(SCE_MMIXAL_INCLUDE);
64 } else {
65 sc.SetState(SCE_MMIXAL_LEADWS);
69 // Check if first non whitespace character in line is alphanumeric
70 if (sc.state == SCE_MMIXAL_LEADWS && !isspace(sc.ch)) { // LEADWS
71 if(!IsAWordChar(sc.ch)) {
72 sc.SetState(SCE_MMIXAL_COMMENT);
73 } else {
74 if(sc.atLineStart) {
75 sc.SetState(SCE_MMIXAL_LABEL);
76 } else {
77 sc.SetState(SCE_MMIXAL_OPCODE_PRE);
82 // Determine if the current state should terminate.
83 if (sc.state == SCE_MMIXAL_OPERATOR) { // OPERATOR
84 sc.SetState(SCE_MMIXAL_OPERANDS);
85 } else if (sc.state == SCE_MMIXAL_NUMBER) { // NUMBER
86 if (!isdigit(sc.ch)) {
87 if (IsAWordChar(sc.ch)) {
88 char s[100];
89 sc.GetCurrent(s, sizeof(s));
90 sc.ChangeState(SCE_MMIXAL_REF);
91 sc.SetState(SCE_MMIXAL_REF);
92 } else {
93 sc.SetState(SCE_MMIXAL_OPERANDS);
96 } else if (sc.state == SCE_MMIXAL_LABEL) { // LABEL
97 if (!IsAWordChar(sc.ch) ) {
98 sc.SetState(SCE_MMIXAL_OPCODE_PRE);
100 } else if (sc.state == SCE_MMIXAL_REF) { // REF
101 if (!IsAWordChar(sc.ch) ) {
102 char s[100];
103 sc.GetCurrent(s, sizeof(s));
104 if (*s == ':') { // ignore base prefix for match
105 for (size_t i = 0; i != sizeof(s); ++i) {
106 *(s+i) = *(s+i+1);
109 if (special_register.InList(s)) {
110 sc.ChangeState(SCE_MMIXAL_REGISTER);
111 } else if (predef_symbols.InList(s)) {
112 sc.ChangeState(SCE_MMIXAL_SYMBOL);
114 sc.SetState(SCE_MMIXAL_OPERANDS);
116 } else if (sc.state == SCE_MMIXAL_OPCODE_PRE) { // OPCODE_PRE
117 if (!isspace(sc.ch)) {
118 sc.SetState(SCE_MMIXAL_OPCODE);
120 } else if (sc.state == SCE_MMIXAL_OPCODE) { // OPCODE
121 if (!IsAWordChar(sc.ch) ) {
122 char s[100];
123 sc.GetCurrent(s, sizeof(s));
124 if (opcodes.InList(s)) {
125 sc.ChangeState(SCE_MMIXAL_OPCODE_VALID);
126 } else {
127 sc.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN);
129 sc.SetState(SCE_MMIXAL_OPCODE_POST);
131 } else if (sc.state == SCE_MMIXAL_STRING) { // STRING
132 if (sc.ch == '\"') {
133 sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
134 } else if (sc.atLineEnd) {
135 sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
137 } else if (sc.state == SCE_MMIXAL_CHAR) { // CHAR
138 if (sc.ch == '\'') {
139 sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
140 } else if (sc.atLineEnd) {
141 sc.ForwardSetState(SCE_MMIXAL_OPERANDS);
143 } else if (sc.state == SCE_MMIXAL_REGISTER) { // REGISTER
144 if (!isdigit(sc.ch)) {
145 sc.SetState(SCE_MMIXAL_OPERANDS);
147 } else if (sc.state == SCE_MMIXAL_HEX) { // HEX
148 if (!isxdigit(sc.ch)) {
149 sc.SetState(SCE_MMIXAL_OPERANDS);
153 // Determine if a new state should be entered.
154 if (sc.state == SCE_MMIXAL_OPCODE_POST || // OPCODE_POST
155 sc.state == SCE_MMIXAL_OPERANDS) { // OPERANDS
156 if (sc.state == SCE_MMIXAL_OPERANDS && isspace(sc.ch)) {
157 if (!sc.atLineEnd) {
158 sc.SetState(SCE_MMIXAL_COMMENT);
160 } else if (isdigit(sc.ch)) {
161 sc.SetState(SCE_MMIXAL_NUMBER);
162 } else if (IsAWordChar(sc.ch) || sc.Match('@')) {
163 sc.SetState(SCE_MMIXAL_REF);
164 } else if (sc.Match('\"')) {
165 sc.SetState(SCE_MMIXAL_STRING);
166 } else if (sc.Match('\'')) {
167 sc.SetState(SCE_MMIXAL_CHAR);
168 } else if (sc.Match('$')) {
169 sc.SetState(SCE_MMIXAL_REGISTER);
170 } else if (sc.Match('#')) {
171 sc.SetState(SCE_MMIXAL_HEX);
172 } else if (isMMIXALOperator(static_cast<char>(sc.ch))) {
173 sc.SetState(SCE_MMIXAL_OPERATOR);
177 sc.Complete();
180 static const char * const MMIXALWordListDesc[] = {
181 "Operation Codes",
182 "Special Register",
183 "Predefined Symbols",
187 LexerModule lmMMIXAL(SCLEX_MMIXAL, ColouriseMMIXALDoc, "mmixal", 0, MMIXALWordListDesc);