1
// Scintilla source code edit control
5
// Copyright 2006 by Fabien Proriol
6
// The License.txt file describes the conditions under which this software may be distributed.
17
#include "Scintilla.h"
21
#include "LexAccessor.h"
23
#include "StyleContext.h"
24
#include "CharacterSet.h"
25
#include "LexerModule.h"
28
using namespace Scintilla;
35
static void ColouriseDocument(
36
unsigned int startPos,
39
WordList *keywordlists[],
42
static const char * const spiceWordListDesc[] = {
43
"Keywords", // SPICE command
44
"Keywords2", // SPICE functions
45
"Keywords3", // SPICE params
49
LexerModule lmSpice(SCLEX_SPICE, ColouriseDocument, "spice", NULL, spiceWordListDesc);
55
static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
56
static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
57
static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
58
static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
59
static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute);
61
static inline bool IsDelimiterCharacter(int ch);
62
static inline bool IsNumberStartCharacter(int ch);
63
static inline bool IsNumberCharacter(int ch);
64
static inline bool IsSeparatorOrDelimiterCharacter(int ch);
65
static inline bool IsWordStartCharacter(int ch);
66
static inline bool IsWordCharacter(int ch);
68
static void ColouriseComment(StyleContext& sc, bool&) {
69
sc.SetState(SCE_SPICE_COMMENTLINE);
70
while (!sc.atLineEnd) {
75
static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
76
apostropheStartsAttribute = sc.Match (')');
77
sc.SetState(SCE_SPICE_DELIMITER);
78
sc.ForwardSetState(SCE_SPICE_DEFAULT);
81
static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
82
apostropheStartsAttribute = true;
84
sc.SetState(SCE_SPICE_NUMBER);
85
// Get all characters up to a delimiter or a separator, including points, but excluding
86
// double points (ranges).
87
while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
88
number += static_cast<char>(sc.ch);
91
// Special case: exponent with sign
92
if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
93
(sc.ch == '+' || sc.ch == '-')) {
94
number += static_cast<char>(sc.ch);
96
while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
97
number += static_cast<char>(sc.ch);
101
sc.SetState(SCE_SPICE_DEFAULT);
104
static void ColouriseWhiteSpace(StyleContext& sc, bool& ) {
105
sc.SetState(SCE_SPICE_DEFAULT);
106
sc.ForwardSetState(SCE_SPICE_DEFAULT);
109
static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) {
110
apostropheStartsAttribute = true;
111
sc.SetState(SCE_SPICE_IDENTIFIER);
113
while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
114
word += static_cast<char>(tolower(sc.ch));
117
if (keywords.InList(word.c_str())) {
118
sc.ChangeState(SCE_SPICE_KEYWORD);
120
apostropheStartsAttribute = false;
123
else if (keywords2.InList(word.c_str())) {
124
sc.ChangeState(SCE_SPICE_KEYWORD2);
126
apostropheStartsAttribute = false;
129
else if (keywords3.InList(word.c_str())) {
130
sc.ChangeState(SCE_SPICE_KEYWORD3);
132
apostropheStartsAttribute = false;
135
sc.SetState(SCE_SPICE_DEFAULT);
141
static void ColouriseDocument(
142
unsigned int startPos,
145
WordList *keywordlists[],
147
WordList &keywords = *keywordlists[0];
148
WordList &keywords2 = *keywordlists[1];
149
WordList &keywords3 = *keywordlists[2];
150
StyleContext sc(startPos, length, initStyle, styler);
151
int lineCurrent = styler.GetLine(startPos);
152
bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
155
// Go to the next line
158
// Remember the line state for future incremental lexing
159
styler.SetLineState(lineCurrent, apostropheStartsAttribute);
160
// Don't continue any styles on the next line
161
sc.SetState(SCE_SPICE_DEFAULT);
164
if ((sc.Match('*') && sc.atLineStart) || sc.Match('*','~')) {
165
ColouriseComment(sc, apostropheStartsAttribute);
167
} else if (IsASpace(sc.ch)) {
168
ColouriseWhiteSpace(sc, apostropheStartsAttribute);
170
} else if (IsDelimiterCharacter(sc.ch)) {
171
ColouriseDelimiter(sc, apostropheStartsAttribute);
173
} else if (IsADigit(sc.ch) || sc.ch == '#') {
174
ColouriseNumber(sc, apostropheStartsAttribute);
175
// Keywords or identifiers
177
ColouriseWord(sc, keywords, keywords2, keywords3, apostropheStartsAttribute);
183
static inline bool IsDelimiterCharacter(int ch) {
207
static inline bool IsNumberCharacter(int ch) {
208
return IsNumberStartCharacter(ch) ||
212
(ch >= 'a' && ch <= 'f') ||
213
(ch >= 'A' && ch <= 'F');
216
static inline bool IsNumberStartCharacter(int ch) {
220
static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
221
return IsASpace(ch) || IsDelimiterCharacter(ch);
224
static inline bool IsWordCharacter(int ch) {
225
return IsWordStartCharacter(ch) || IsADigit(ch);
228
static inline bool IsWordStartCharacter(int ch) {
229
return (isascii(ch) && isalpha(ch)) || ch == '_';