Scintilla 4.0.3
[TortoiseGit.git] / ext / scintilla / lexers / LexForth.cxx
blobdf620794fff187f1345b9ec44ef5ac8a3b4bc01a
1 // Scintilla source code edit control
2 /** @file LexForth.cxx
3 ** Lexer for FORTH
4 **/
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.
8 #include <stdlib.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <stdarg.h>
12 #include <assert.h>
13 #include <ctype.h>
15 #include "ILexer.h"
16 #include "Scintilla.h"
17 #include "SciLexer.h"
19 #include "WordList.h"
20 #include "LexAccessor.h"
21 #include "Accessor.h"
22 #include "StyleContext.h"
23 #include "CharacterSet.h"
24 #include "LexerModule.h"
26 using namespace Scintilla;
28 static inline bool IsAWordStart(int ch) {
29 return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
32 static inline bool IsANumChar(int ch) {
33 return (ch < 0x80) && (isxdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' );
36 static inline bool IsASpaceChar(int ch) {
37 return (ch < 0x80) && isspace(ch);
40 static void ColouriseForthDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordLists[],
41 Accessor &styler) {
43 WordList &control = *keywordLists[0];
44 WordList &keyword = *keywordLists[1];
45 WordList &defword = *keywordLists[2];
46 WordList &preword1 = *keywordLists[3];
47 WordList &preword2 = *keywordLists[4];
48 WordList &strings = *keywordLists[5];
50 StyleContext sc(startPos, length, initStyle, styler);
52 for (; sc.More(); sc.Forward())
54 // Determine if the current state should terminate.
55 if (sc.state == SCE_FORTH_COMMENT) {
56 if (sc.atLineEnd) {
57 sc.SetState(SCE_FORTH_DEFAULT);
59 }else if (sc.state == SCE_FORTH_COMMENT_ML) {
60 if (sc.ch == ')') {
61 sc.ForwardSetState(SCE_FORTH_DEFAULT);
63 }else if (sc.state == SCE_FORTH_IDENTIFIER || sc.state == SCE_FORTH_NUMBER) {
64 // handle numbers here too, because what we thought was a number might
65 // turn out to be a keyword e.g. 2DUP
66 if (IsASpaceChar(sc.ch) ) {
67 char s[100];
68 sc.GetCurrentLowered(s, sizeof(s));
69 int newState = sc.state == SCE_FORTH_NUMBER ? SCE_FORTH_NUMBER : SCE_FORTH_DEFAULT;
70 if (control.InList(s)) {
71 sc.ChangeState(SCE_FORTH_CONTROL);
72 } else if (keyword.InList(s)) {
73 sc.ChangeState(SCE_FORTH_KEYWORD);
74 } else if (defword.InList(s)) {
75 sc.ChangeState(SCE_FORTH_DEFWORD);
76 } else if (preword1.InList(s)) {
77 sc.ChangeState(SCE_FORTH_PREWORD1);
78 } else if (preword2.InList(s)) {
79 sc.ChangeState(SCE_FORTH_PREWORD2);
80 } else if (strings.InList(s)) {
81 sc.ChangeState(SCE_FORTH_STRING);
82 newState = SCE_FORTH_STRING;
84 sc.SetState(newState);
86 if (sc.state == SCE_FORTH_NUMBER) {
87 if (IsASpaceChar(sc.ch)) {
88 sc.SetState(SCE_FORTH_DEFAULT);
89 } else if (!IsANumChar(sc.ch)) {
90 sc.ChangeState(SCE_FORTH_IDENTIFIER);
93 }else if (sc.state == SCE_FORTH_STRING) {
94 if (sc.ch == '\"') {
95 sc.ForwardSetState(SCE_FORTH_DEFAULT);
97 }else if (sc.state == SCE_FORTH_LOCALE) {
98 if (sc.ch == '}') {
99 sc.ForwardSetState(SCE_FORTH_DEFAULT);
101 }else if (sc.state == SCE_FORTH_DEFWORD) {
102 if (IsASpaceChar(sc.ch)) {
103 sc.SetState(SCE_FORTH_DEFAULT);
107 // Determine if a new state should be entered.
108 if (sc.state == SCE_FORTH_DEFAULT) {
109 if (sc.ch == '\\'){
110 sc.SetState(SCE_FORTH_COMMENT);
111 } else if (sc.ch == '(' &&
112 (sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
113 (sc.atLineEnd || IsASpaceChar(sc.chNext))) {
114 sc.SetState(SCE_FORTH_COMMENT_ML);
115 } else if ( (sc.ch == '$' && (IsASCII(sc.chNext) && isxdigit(sc.chNext))) ) {
116 // number starting with $ is a hex number
117 sc.SetState(SCE_FORTH_NUMBER);
118 while(sc.More() && IsASCII(sc.chNext) && isxdigit(sc.chNext))
119 sc.Forward();
120 } else if ( (sc.ch == '%' && (IsASCII(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))) ) {
121 // number starting with % is binary
122 sc.SetState(SCE_FORTH_NUMBER);
123 while(sc.More() && IsASCII(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))
124 sc.Forward();
125 } else if ( IsASCII(sc.ch) &&
126 (isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && IsASCII(sc.chNext) && isxdigit(sc.chNext)) )
128 sc.SetState(SCE_FORTH_NUMBER);
129 } else if (IsAWordStart(sc.ch)) {
130 sc.SetState(SCE_FORTH_IDENTIFIER);
131 } else if (sc.ch == '{') {
132 sc.SetState(SCE_FORTH_LOCALE);
133 } else if (sc.ch == ':' && IsASCII(sc.chNext) && isspace(sc.chNext)) {
134 // highlight word definitions e.g. : GCD ( n n -- n ) ..... ;
135 // ^ ^^^
136 sc.SetState(SCE_FORTH_DEFWORD);
137 while(sc.More() && IsASCII(sc.chNext) && isspace(sc.chNext))
138 sc.Forward();
139 } else if (sc.ch == ';' &&
140 (sc.atLineStart || IsASpaceChar(sc.chPrev)) &&
141 (sc.atLineEnd || IsASpaceChar(sc.chNext)) ) {
142 // mark the ';' that ends a word
143 sc.SetState(SCE_FORTH_DEFWORD);
144 sc.ForwardSetState(SCE_FORTH_DEFAULT);
149 sc.Complete();
152 static void FoldForthDoc(Sci_PositionU, Sci_Position, int, WordList *[],
153 Accessor &) {
156 static const char * const forthWordLists[] = {
157 "control keywords",
158 "keywords",
159 "definition words",
160 "prewords with one argument",
161 "prewords with two arguments",
162 "string definition keywords",
166 LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists);