]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/lexers/LexForth.cxx
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.
16 #include "Scintilla.h"
20 #include "LexAccessor.h"
22 #include "StyleContext.h"
23 #include "CharacterSet.h"
24 #include "LexerModule.h"
27 using namespace Scintilla
;
30 static inline bool IsAWordChar(int ch
) {
31 return (ch
< 0x80) && (isalnum(ch
) || ch
== '.' ||
32 ch
== '_' || ch
== '?' || ch
== '"' || ch
== '@' ||
33 ch
== '!' || ch
== '[' || ch
== ']' || ch
== '/' ||
34 ch
== '+' || ch
== '-' || ch
== '*' || ch
== '<' ||
35 ch
== '>' || ch
== '=' || ch
== ';' || ch
== '(' ||
39 static inline bool IsAWordStart(int ch
) {
40 return (ch
< 0x80) && (isalnum(ch
) || ch
== '_' || ch
== '.');
43 static inline bool IsANumChar(int ch
) {
44 return (ch
< 0x80) && (isxdigit(ch
) || ch
== '.' || ch
== 'e' || ch
== 'E' );
47 static inline bool IsASpaceChar(int ch
) {
48 return (ch
< 0x80) && isspace(ch
);
51 static void ColouriseForthDoc(unsigned int startPos
, int length
, int initStyle
, WordList
*keywordLists
[],
54 WordList
&control
= *keywordLists
[0];
55 WordList
&keyword
= *keywordLists
[1];
56 WordList
&defword
= *keywordLists
[2];
57 WordList
&preword1
= *keywordLists
[3];
58 WordList
&preword2
= *keywordLists
[4];
59 WordList
&strings
= *keywordLists
[5];
61 StyleContext
sc(startPos
, length
, initStyle
, styler
);
63 for (; sc
.More(); sc
.Forward())
65 // Determine if the current state should terminate.
66 if (sc
.state
== SCE_FORTH_COMMENT
) {
68 sc
.SetState(SCE_FORTH_DEFAULT
);
70 }else if (sc
.state
== SCE_FORTH_COMMENT_ML
) {
72 sc
.ForwardSetState(SCE_FORTH_DEFAULT
);
74 }else if (sc
.state
== SCE_FORTH_IDENTIFIER
|| sc
.state
== SCE_FORTH_NUMBER
) {
75 // handle numbers here too, because what we thought was a number might
76 // turn out to be a keyword e.g. 2DUP
77 if (IsASpaceChar(sc
.ch
) ) {
79 sc
.GetCurrentLowered(s
, sizeof(s
));
80 int newState
= sc
.state
== SCE_FORTH_NUMBER
? SCE_FORTH_NUMBER
: SCE_FORTH_DEFAULT
;
81 if (control
.InList(s
)) {
82 sc
.ChangeState(SCE_FORTH_CONTROL
);
83 } else if (keyword
.InList(s
)) {
84 sc
.ChangeState(SCE_FORTH_KEYWORD
);
85 } else if (defword
.InList(s
)) {
86 sc
.ChangeState(SCE_FORTH_DEFWORD
);
87 } else if (preword1
.InList(s
)) {
88 sc
.ChangeState(SCE_FORTH_PREWORD1
);
89 } else if (preword2
.InList(s
)) {
90 sc
.ChangeState(SCE_FORTH_PREWORD2
);
91 } else if (strings
.InList(s
)) {
92 sc
.ChangeState(SCE_FORTH_STRING
);
93 newState
= SCE_FORTH_STRING
;
95 sc
.SetState(newState
);
97 if (sc
.state
== SCE_FORTH_NUMBER
) {
98 if (IsASpaceChar(sc
.ch
)) {
99 sc
.SetState(SCE_FORTH_DEFAULT
);
100 } else if (!IsANumChar(sc
.ch
)) {
101 sc
.ChangeState(SCE_FORTH_IDENTIFIER
);
104 }else if (sc
.state
== SCE_FORTH_STRING
) {
106 sc
.ForwardSetState(SCE_FORTH_DEFAULT
);
108 }else if (sc
.state
== SCE_FORTH_LOCALE
) {
110 sc
.ForwardSetState(SCE_FORTH_DEFAULT
);
112 }else if (sc
.state
== SCE_FORTH_DEFWORD
) {
113 if (IsASpaceChar(sc
.ch
)) {
114 sc
.SetState(SCE_FORTH_DEFAULT
);
118 // Determine if a new state should be entered.
119 if (sc
.state
== SCE_FORTH_DEFAULT
) {
121 sc
.SetState(SCE_FORTH_COMMENT
);
122 } else if (sc
.ch
== '(' &&
123 (sc
.atLineStart
|| IsASpaceChar(sc
.chPrev
)) &&
124 (sc
.atLineEnd
|| IsASpaceChar(sc
.chNext
))) {
125 sc
.SetState(SCE_FORTH_COMMENT_ML
);
126 } else if ( (sc
.ch
== '$' && (isascii(sc
.chNext
) && isxdigit(sc
.chNext
))) ) {
127 // number starting with $ is a hex number
128 sc
.SetState(SCE_FORTH_NUMBER
);
129 while(sc
.More() && isascii(sc
.chNext
) && isxdigit(sc
.chNext
))
131 } else if ( (sc
.ch
== '%' && (isascii(sc
.chNext
) && (sc
.chNext
== '0' || sc
.chNext
== '1'))) ) {
132 // number starting with % is binary
133 sc
.SetState(SCE_FORTH_NUMBER
);
134 while(sc
.More() && isascii(sc
.chNext
) && (sc
.chNext
== '0' || sc
.chNext
== '1'))
136 } else if ( isascii(sc
.ch
) &&
137 (isxdigit(sc
.ch
) || ((sc
.ch
== '.' || sc
.ch
== '-') && isascii(sc
.chNext
) && isxdigit(sc
.chNext
)) )
139 sc
.SetState(SCE_FORTH_NUMBER
);
140 } else if (IsAWordStart(sc
.ch
)) {
141 sc
.SetState(SCE_FORTH_IDENTIFIER
);
142 } else if (sc
.ch
== '{') {
143 sc
.SetState(SCE_FORTH_LOCALE
);
144 } else if (sc
.ch
== ':' && isascii(sc
.chNext
) && isspace(sc
.chNext
)) {
145 // highlight word definitions e.g. : GCD ( n n -- n ) ..... ;
147 sc
.SetState(SCE_FORTH_DEFWORD
);
148 while(sc
.More() && isascii(sc
.chNext
) && isspace(sc
.chNext
))
150 } else if (sc
.ch
== ';' &&
151 (sc
.atLineStart
|| IsASpaceChar(sc
.chPrev
)) &&
152 (sc
.atLineEnd
|| IsASpaceChar(sc
.chNext
)) ) {
153 // mark the ';' that ends a word
154 sc
.SetState(SCE_FORTH_DEFWORD
);
155 sc
.ForwardSetState(SCE_FORTH_DEFAULT
);
163 static void FoldForthDoc(unsigned int, int, int, WordList
*[],
167 static const char * const forthWordLists
[] = {
171 "prewords with one argument",
172 "prewords with two arguments",
173 "string definition keywords",
177 LexerModule
lmForth(SCLEX_FORTH
, ColouriseForthDoc
, "forth", FoldForthDoc
, forthWordLists
);