]> git.saurik.com Git - wxWidgets.git/blame - src/stc/scintilla/lexers/LexSpice.cxx
Add missing WXK constants for the control keys
[wxWidgets.git] / src / stc / scintilla / lexers / LexSpice.cxx
CommitLineData
b8193d80
RD
1// Scintilla source code edit control
2/** @file LexSpice.cxx
3 ** Lexer for Spice
4 **/
5// Copyright 2006 by Fabien Proriol
6// The License.txt file describes the conditions under which this software may be distributed.
7
8#include <stdlib.h>
b8193d80
RD
9#include <string.h>
10#include <stdio.h>
1dcf666d
RD
11#include <stdarg.h>
12#include <assert.h>
13#include <ctype.h>
b8193d80 14
9e96e16f
RD
15#include <string>
16
1dcf666d
RD
17#include "ILexer.h"
18#include "Scintilla.h"
19#include "SciLexer.h"
b8193d80 20
1dcf666d
RD
21#include "WordList.h"
22#include "LexAccessor.h"
b8193d80
RD
23#include "Accessor.h"
24#include "StyleContext.h"
1dcf666d
RD
25#include "CharacterSet.h"
26#include "LexerModule.h"
b8193d80 27
7e0c58e9
RD
28#ifdef SCI_NAMESPACE
29using namespace Scintilla;
30#endif
31
b8193d80
RD
32/*
33 * Interface
34 */
35
36static void ColouriseDocument(
37 unsigned int startPos,
38 int length,
39 int initStyle,
40 WordList *keywordlists[],
41 Accessor &styler);
42
43static const char * const spiceWordListDesc[] = {
44 "Keywords", // SPICE command
45 "Keywords2", // SPICE functions
46 "Keywords3", // SPICE params
47 0
48};
49
50LexerModule lmSpice(SCLEX_SPICE, ColouriseDocument, "spice", NULL, spiceWordListDesc);
51
52/*
53 * Implementation
54 */
55
56static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
57static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
58static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
59static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
60static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute);
61
62static inline bool IsDelimiterCharacter(int ch);
63static inline bool IsNumberStartCharacter(int ch);
64static inline bool IsNumberCharacter(int ch);
65static inline bool IsSeparatorOrDelimiterCharacter(int ch);
66static inline bool IsWordStartCharacter(int ch);
67static inline bool IsWordCharacter(int ch);
68
69static void ColouriseComment(StyleContext& sc, bool&) {
70 sc.SetState(SCE_SPICE_COMMENTLINE);
71 while (!sc.atLineEnd) {
72 sc.Forward();
73 }
74}
75
76static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
77 apostropheStartsAttribute = sc.Match (')');
78 sc.SetState(SCE_SPICE_DELIMITER);
79 sc.ForwardSetState(SCE_SPICE_DEFAULT);
80}
81
82static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
83 apostropheStartsAttribute = true;
9e96e16f 84 std::string number;
b8193d80
RD
85 sc.SetState(SCE_SPICE_NUMBER);
86 // Get all characters up to a delimiter or a separator, including points, but excluding
87 // double points (ranges).
88 while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
89 number += static_cast<char>(sc.ch);
90 sc.Forward();
91 }
92 // Special case: exponent with sign
93 if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
94 (sc.ch == '+' || sc.ch == '-')) {
95 number += static_cast<char>(sc.ch);
96 sc.Forward ();
97 while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
98 number += static_cast<char>(sc.ch);
99 sc.Forward();
100 }
101 }
102 sc.SetState(SCE_SPICE_DEFAULT);
103}
104
105static void ColouriseWhiteSpace(StyleContext& sc, bool& ) {
106 sc.SetState(SCE_SPICE_DEFAULT);
107 sc.ForwardSetState(SCE_SPICE_DEFAULT);
108}
109
110static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) {
111 apostropheStartsAttribute = true;
112 sc.SetState(SCE_SPICE_IDENTIFIER);
9e96e16f 113 std::string word;
b8193d80
RD
114 while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
115 word += static_cast<char>(tolower(sc.ch));
116 sc.Forward();
117 }
118 if (keywords.InList(word.c_str())) {
119 sc.ChangeState(SCE_SPICE_KEYWORD);
120 if (word != "all") {
121 apostropheStartsAttribute = false;
122 }
123 }
124 else if (keywords2.InList(word.c_str())) {
125 sc.ChangeState(SCE_SPICE_KEYWORD2);
126 if (word != "all") {
127 apostropheStartsAttribute = false;
128 }
129 }
130 else if (keywords3.InList(word.c_str())) {
131 sc.ChangeState(SCE_SPICE_KEYWORD3);
132 if (word != "all") {
133 apostropheStartsAttribute = false;
134 }
135 }
136 sc.SetState(SCE_SPICE_DEFAULT);
137}
138
139//
140// ColouriseDocument
141//
142static void ColouriseDocument(
143 unsigned int startPos,
144 int length,
145 int initStyle,
146 WordList *keywordlists[],
147 Accessor &styler) {
148 WordList &keywords = *keywordlists[0];
149 WordList &keywords2 = *keywordlists[1];
150 WordList &keywords3 = *keywordlists[2];
151 StyleContext sc(startPos, length, initStyle, styler);
152 int lineCurrent = styler.GetLine(startPos);
153 bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
154 while (sc.More()) {
155 if (sc.atLineEnd) {
156 // Go to the next line
157 sc.Forward();
158 lineCurrent++;
159 // Remember the line state for future incremental lexing
160 styler.SetLineState(lineCurrent, apostropheStartsAttribute);
161 // Don't continue any styles on the next line
162 sc.SetState(SCE_SPICE_DEFAULT);
163 }
164 // Comments
165 if ((sc.Match('*') && sc.atLineStart) || sc.Match('*','~')) {
166 ColouriseComment(sc, apostropheStartsAttribute);
167 // Whitespace
168 } else if (IsASpace(sc.ch)) {
169 ColouriseWhiteSpace(sc, apostropheStartsAttribute);
170 // Delimiters
171 } else if (IsDelimiterCharacter(sc.ch)) {
172 ColouriseDelimiter(sc, apostropheStartsAttribute);
173 // Numbers
174 } else if (IsADigit(sc.ch) || sc.ch == '#') {
175 ColouriseNumber(sc, apostropheStartsAttribute);
176 // Keywords or identifiers
177 } else {
178 ColouriseWord(sc, keywords, keywords2, keywords3, apostropheStartsAttribute);
179 }
180 }
181 sc.Complete();
182}
183
184static inline bool IsDelimiterCharacter(int ch) {
185 switch (ch) {
186 case '&':
187 case '\'':
188 case '(':
189 case ')':
190 case '*':
191 case '+':
192 case ',':
193 case '-':
194 case '.':
195 case '/':
196 case ':':
197 case ';':
198 case '<':
199 case '=':
200 case '>':
201 case '|':
202 return true;
203 default:
204 return false;
205 }
206}
207
208static inline bool IsNumberCharacter(int ch) {
209 return IsNumberStartCharacter(ch) ||
210 ch == '_' ||
211 ch == '.' ||
212 ch == '#' ||
213 (ch >= 'a' && ch <= 'f') ||
214 (ch >= 'A' && ch <= 'F');
215}
216
217static inline bool IsNumberStartCharacter(int ch) {
218 return IsADigit(ch);
219}
220
221static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
222 return IsASpace(ch) || IsDelimiterCharacter(ch);
223}
224
225static inline bool IsWordCharacter(int ch) {
226 return IsWordStartCharacter(ch) || IsADigit(ch);
227}
228
229static inline bool IsWordStartCharacter(int ch) {
230 return (isascii(ch) && isalpha(ch)) || ch == '_';
231}