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.
18
#include "Scintilla.h"
22
#include "LexAccessor.h"
24
#include "StyleContext.h"
25
#include "CharacterSet.h"
26
#include "LexerModule.h"
29
using namespace Scintilla;
36
static void ColouriseDocument(
37
unsigned int startPos,
40
WordList *keywordlists[],
43
static const char * const spiceWordListDesc[] = {
44
"Keywords", // SPICE command
45
"Keywords2", // SPICE functions
46
"Keywords3", // SPICE params
50
LexerModule lmSpice(SCLEX_SPICE, ColouriseDocument, "spice", NULL, spiceWordListDesc);
56
static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
57
static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
58
static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
59
static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
60
static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute);
62
static inline bool IsDelimiterCharacter(int ch);
63
static inline bool IsSeparatorOrDelimiterCharacter(int ch);
65
static void ColouriseComment(StyleContext& sc, bool&) {
66
sc.SetState(SCE_SPICE_COMMENTLINE);
67
while (!sc.atLineEnd) {
72
static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
73
apostropheStartsAttribute = sc.Match (')');
74
sc.SetState(SCE_SPICE_DELIMITER);
75
sc.ForwardSetState(SCE_SPICE_DEFAULT);
78
static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
79
apostropheStartsAttribute = true;
81
sc.SetState(SCE_SPICE_NUMBER);
82
// Get all characters up to a delimiter or a separator, including points, but excluding
83
// double points (ranges).
84
while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
85
number += static_cast<char>(sc.ch);
88
// Special case: exponent with sign
89
if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
90
(sc.ch == '+' || sc.ch == '-')) {
91
number += static_cast<char>(sc.ch);
93
while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
94
number += static_cast<char>(sc.ch);
98
sc.SetState(SCE_SPICE_DEFAULT);
101
static void ColouriseWhiteSpace(StyleContext& sc, bool& ) {
102
sc.SetState(SCE_SPICE_DEFAULT);
103
sc.ForwardSetState(SCE_SPICE_DEFAULT);
106
static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) {
107
apostropheStartsAttribute = true;
108
sc.SetState(SCE_SPICE_IDENTIFIER);
110
while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
111
word += static_cast<char>(tolower(sc.ch));
114
if (keywords.InList(word.c_str())) {
115
sc.ChangeState(SCE_SPICE_KEYWORD);
117
apostropheStartsAttribute = false;
120
else if (keywords2.InList(word.c_str())) {
121
sc.ChangeState(SCE_SPICE_KEYWORD2);
123
apostropheStartsAttribute = false;
126
else if (keywords3.InList(word.c_str())) {
127
sc.ChangeState(SCE_SPICE_KEYWORD3);
129
apostropheStartsAttribute = false;
132
sc.SetState(SCE_SPICE_DEFAULT);
138
static void ColouriseDocument(
139
unsigned int startPos,
142
WordList *keywordlists[],
144
WordList &keywords = *keywordlists[0];
145
WordList &keywords2 = *keywordlists[1];
146
WordList &keywords3 = *keywordlists[2];
147
StyleContext sc(startPos, length, initStyle, styler);
148
int lineCurrent = styler.GetLine(startPos);
149
bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
152
// Go to the next line
155
// Remember the line state for future incremental lexing
156
styler.SetLineState(lineCurrent, apostropheStartsAttribute);
157
// Don't continue any styles on the next line
158
sc.SetState(SCE_SPICE_DEFAULT);
161
if ((sc.Match('*') && sc.atLineStart) || sc.Match('*','~')) {
162
ColouriseComment(sc, apostropheStartsAttribute);
164
} else if (IsASpace(sc.ch)) {
165
ColouriseWhiteSpace(sc, apostropheStartsAttribute);
167
} else if (IsDelimiterCharacter(sc.ch)) {
168
ColouriseDelimiter(sc, apostropheStartsAttribute);
170
} else if (IsADigit(sc.ch) || sc.ch == '#') {
171
ColouriseNumber(sc, apostropheStartsAttribute);
172
// Keywords or identifiers
174
ColouriseWord(sc, keywords, keywords2, keywords3, apostropheStartsAttribute);
180
static inline bool IsDelimiterCharacter(int ch) {
204
static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
205
return IsASpace(ch) || IsDelimiterCharacter(ch);