1
// Scintilla source code edit control
5
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
6
// The License.txt file describes the conditions under which this software may be distributed.
18
#include "StyleContext.h"
20
#include "Scintilla.h"
24
using namespace Scintilla;
27
static inline bool IsAWordChar(int ch) {
28
return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
29
ch == '_' || ch == '?' || ch == '"' || ch == '@' ||
30
ch == '!' || ch == '[' || ch == ']' || ch == '/' ||
31
ch == '+' || ch == '-' || ch == '*' || ch == '<' ||
32
ch == '>' || ch == '=' || ch == ';' || ch == '(' ||
36
static inline bool IsAWordStart(int ch) {
37
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
40
static inline bool IsANumChar(int ch) {
41
return (ch < 0x80) && (isxdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' );
44
static inline bool IsASpaceChar(int ch) {
45
return (ch < 0x80) && isspace(ch);
48
static void ColouriseForthDoc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[],
51
WordList &control = *keywordLists[0];
52
WordList &keyword = *keywordLists[1];
53
WordList &defword = *keywordLists[2];
54
WordList &preword1 = *keywordLists[3];
55
WordList &preword2 = *keywordLists[4];
56
WordList &strings = *keywordLists[5];
58
StyleContext sc(startPos, length, initStyle, styler);
60
for (; sc.More(); sc.Forward())
62
// Determine if the current state should terminate.
63
if (sc.state == SCE_FORTH_COMMENT) {
65
sc.SetState(SCE_FORTH_DEFAULT);
67
}else if (sc.state == SCE_FORTH_COMMENT_ML) {
69
sc.ForwardSetState(SCE_FORTH_DEFAULT);
71
}else if (sc.state == SCE_FORTH_IDENTIFIER || sc.state == SCE_FORTH_NUMBER) {
72
// handle numbers here too, because what we thought was a number might
73
// turn out to be a keyword e.g. 2DUP
74
if (IsASpaceChar(sc.ch) ) {
76
sc.GetCurrentLowered(s, sizeof(s));
77
int newState = sc.state == SCE_FORTH_NUMBER ? SCE_FORTH_NUMBER : SCE_FORTH_DEFAULT;
78
if (control.InList(s)) {
79
sc.ChangeState(SCE_FORTH_CONTROL);
80
} else if (keyword.InList(s)) {
81
sc.ChangeState(SCE_FORTH_KEYWORD);
82
} else if (defword.InList(s)) {
83
sc.ChangeState(SCE_FORTH_DEFWORD);
84
} else if (preword1.InList(s)) {
85
sc.ChangeState(SCE_FORTH_PREWORD1);
86
} else if (preword2.InList(s)) {
87
sc.ChangeState(SCE_FORTH_PREWORD2);
88
} else if (strings.InList(s)) {
89
sc.ChangeState(SCE_FORTH_STRING);
90
newState = SCE_FORTH_STRING;
92
sc.SetState(newState);
94
if (sc.state == SCE_FORTH_NUMBER) {
95
if (IsASpaceChar(sc.ch)) {
96
sc.SetState(SCE_FORTH_DEFAULT);
97
} else if (!IsANumChar(sc.ch)) {
98
sc.ChangeState(SCE_FORTH_IDENTIFIER);
101
}else if (sc.state == SCE_FORTH_STRING) {
103
sc.ForwardSetState(SCE_FORTH_DEFAULT);
105
}else if (sc.state == SCE_FORTH_LOCALE) {
107
sc.ForwardSetState(SCE_FORTH_DEFAULT);
109
}else if (sc.state == SCE_FORTH_DEFWORD) {
110
if (IsASpaceChar(sc.ch)) {
111
sc.SetState(SCE_FORTH_DEFAULT);
115
// Determine if a new state should be entered.
116
if (sc.state == SCE_FORTH_DEFAULT) {
118
sc.SetState(SCE_FORTH_COMMENT);
119
} else if (sc.ch == '(' &&
120
(sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
121
(sc.atLineEnd || IsASpaceChar(sc.chNext))) {
122
sc.SetState(SCE_FORTH_COMMENT_ML);
123
} else if ( (sc.ch == '$' && (isascii(sc.chNext) && isxdigit(sc.chNext))) ) {
124
// number starting with $ is a hex number
125
sc.SetState(SCE_FORTH_NUMBER);
126
while(sc.More() && isascii(sc.chNext) && isxdigit(sc.chNext))
128
} else if ( (sc.ch == '%' && (isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))) ) {
129
// number starting with % is binary
130
sc.SetState(SCE_FORTH_NUMBER);
131
while(sc.More() && isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))
133
} else if ( isascii(sc.ch) &&
134
(isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && isascii(sc.chNext) && isxdigit(sc.chNext)) )
136
sc.SetState(SCE_FORTH_NUMBER);
137
} else if (IsAWordStart(sc.ch)) {
138
sc.SetState(SCE_FORTH_IDENTIFIER);
139
} else if (sc.ch == '{') {
140
sc.SetState(SCE_FORTH_LOCALE);
141
} else if (sc.ch == ':' && isascii(sc.chNext) && isspace(sc.chNext)) {
142
// highlight word definitions e.g. : GCD ( n n -- n ) ..... ;
144
sc.SetState(SCE_FORTH_DEFWORD);
145
while(sc.More() && isascii(sc.chNext) && isspace(sc.chNext))
147
} else if (sc.ch == ';' &&
148
(sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
149
(sc.atLineEnd || IsASpaceChar(sc.chNext)) ) {
150
// mark the ';' that ends a word
151
sc.SetState(SCE_FORTH_DEFWORD);
152
sc.ForwardSetState(SCE_FORTH_DEFAULT);
160
static void FoldForthDoc(unsigned int, int, int, WordList *[],
164
static const char * const forthWordLists[] = {
168
"prewords with one argument",
169
"prewords with two arguments",
170
"string definition keywords",
174
LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists);