]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexForth.cxx
e52543fa552da9e9b1a6c396a08a439981f5a089
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
);