Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 177 lines (157 sloc) 5.763 kb
f858c4b Dan Savilonis Import Scintilla 2.11
authored
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.
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <stdio.h>
12 #include <stdarg.h>
13
14 #include "Platform.h"
15
16 #include "PropSet.h"
17 #include "Accessor.h"
18 #include "StyleContext.h"
19 #include "KeyWords.h"
20 #include "Scintilla.h"
21 #include "SciLexer.h"
22
23 #ifdef SCI_NAMESPACE
24 using namespace Scintilla;
25 #endif
26
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 == '(' ||
33 ch == ')' );
34 }
35
36 static inline bool IsAWordStart(int ch) {
37 return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
38 }
39
40 static inline bool IsANumChar(int ch) {
41 return (ch < 0x80) && (isxdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' );
42 }
43
44 static inline bool IsASpaceChar(int ch) {
45 return (ch < 0x80) && isspace(ch);
46 }
47
48 static void ColouriseForthDoc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[],
49 Accessor &styler) {
50
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];
57
58 StyleContext sc(startPos, length, initStyle, styler);
59
60 for (; sc.More(); sc.Forward())
61 {
62 // Determine if the current state should terminate.
63 if (sc.state == SCE_FORTH_COMMENT) {
64 if (sc.atLineEnd) {
65 sc.SetState(SCE_FORTH_DEFAULT);
66 }
67 }else if (sc.state == SCE_FORTH_COMMENT_ML) {
68 if (sc.ch == ')') {
69 sc.ForwardSetState(SCE_FORTH_DEFAULT);
70 }
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) ) {
75 char s[100];
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;
91 }
92 sc.SetState(newState);
93 }
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);
99 }
100 }
101 }else if (sc.state == SCE_FORTH_STRING) {
102 if (sc.ch == '\"') {
103 sc.ForwardSetState(SCE_FORTH_DEFAULT);
104 }
105 }else if (sc.state == SCE_FORTH_LOCALE) {
106 if (sc.ch == '}') {
107 sc.ForwardSetState(SCE_FORTH_DEFAULT);
108 }
109 }else if (sc.state == SCE_FORTH_DEFWORD) {
110 if (IsASpaceChar(sc.ch)) {
111 sc.SetState(SCE_FORTH_DEFAULT);
112 }
113 }
114
115 // Determine if a new state should be entered.
116 if (sc.state == SCE_FORTH_DEFAULT) {
117 if (sc.ch == '\\'){
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))
127 sc.Forward();
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'))
132 sc.Forward();
133 } else if ( isascii(sc.ch) &&
134 (isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && isascii(sc.chNext) && isxdigit(sc.chNext)) )
135 ){
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 ) ..... ;
143 // ^ ^^^
144 sc.SetState(SCE_FORTH_DEFWORD);
145 while(sc.More() && isascii(sc.chNext) && isspace(sc.chNext))
146 sc.Forward();
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);
153 }
154 }
155
156 }
157 sc.Complete();
158 }
159
160 static void FoldForthDoc(unsigned int, int, int, WordList *[],
161 Accessor &) {
162 }
163
164 static const char * const forthWordLists[] = {
165 "control keywords",
166 "keywords",
167 "definition words",
168 "prewords with one argument",
169 "prewords with two arguments",
170 "string definition keywords",
171 0,
172 };
173
174 LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists);
175
176
Something went wrong with that request. Please try again.