~efargaspro/+junk/codeblocks-16.01-release

« back to all changes in this revision

Viewing changes to src/plugins/contrib/wxSmithSTC/stc/scintilla/src/LexRebol.cxx

  • Committer: damienlmoore at gmail
  • Date: 2016-02-02 02:43:22 UTC
  • Revision ID: damienlmoore@gmail.com-20160202024322-yql5qmtbwdyamdwd
Code::BlocksĀ 16.01

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Scintilla source code edit control
 
2
/** @file LexRebol.cxx
 
3
 ** Lexer for REBOL.
 
4
 ** Written by Pascal Hurni, inspired from LexLua by Paul Winwood & Marcos E. Wurzius & Philippe Lhoste
 
5
 **
 
6
 ** History:
 
7
 **             2005-04-07      First release.
 
8
 **             2005-04-10      Closing parens and brackets go now in default style
 
9
 **                                     String and comment nesting should be more safe
 
10
 **/
 
11
// Copyright 2005 by Pascal Hurni <pascal_hurni@fastmail.fm>
 
12
// The License.txt file describes the conditions under which this software may be distributed.
 
13
 
 
14
#include <stdlib.h>
 
15
#include <string.h>
 
16
#include <ctype.h>
 
17
#include <stdio.h>
 
18
#include <stdarg.h>
 
19
 
 
20
#include "Platform.h"
 
21
 
 
22
#include "PropSet.h"
 
23
#include "Accessor.h"
 
24
#include "KeyWords.h"
 
25
#include "Scintilla.h"
 
26
#include "SciLexer.h"
 
27
#include "StyleContext.h"
 
28
 
 
29
 
 
30
static inline bool IsAWordChar(const int ch) {
 
31
        return (isalnum(ch) || ch == '?' || ch == '!' || ch == '.' || ch == '\'' || ch == '+' || ch == '-' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');
 
32
}
 
33
 
 
34
static inline bool IsAWordStart(const int ch, const int ch2) {
 
35
        return ((ch == '+' || ch == '-' || ch == '.') && !isdigit(ch2)) ||
 
36
                (isalpha(ch) || ch == '?' || ch == '!' || ch == '\'' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~');
 
37
}
 
38
 
 
39
static inline bool IsAnOperator(const int ch, const int ch2, const int ch3) {
 
40
        // One char operators
 
41
        if (IsASpaceOrTab(ch2)) {
 
42
                return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '<' || ch == '>' || ch == '=' || ch == '?';
 
43
        }
 
44
 
 
45
        // Two char operators
 
46
        if (IsASpaceOrTab(ch3)) {
 
47
                return (ch == '*' && ch2 == '*') ||
 
48
                           (ch == '/' && ch2 == '/') ||
 
49
                           (ch == '<' && (ch2 == '=' || ch2 == '>')) ||
 
50
                           (ch == '>' && ch2 == '=') ||
 
51
                           (ch == '=' && (ch2 == '=' || ch2 == '?')) ||
 
52
                           (ch == '?' && ch2 == '?');
 
53
        }
 
54
 
 
55
        return false;
 
56
}
 
57
 
 
58
static inline bool IsBinaryStart(const int ch, const int ch2, const int ch3, const int ch4) {
 
59
        return (ch == '#' && ch2 == '{') ||
 
60
                   (IsADigit(ch) && ch2 == '#' && ch3 == '{' ) ||
 
61
                   (IsADigit(ch) && IsADigit(ch2) && ch3 == '#' && ch4 == '{' );
 
62
}
 
63
 
 
64
 
 
65
static void ColouriseRebolDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {
 
66
 
 
67
        WordList &keywords = *keywordlists[0];
 
68
        WordList &keywords2 = *keywordlists[1];
 
69
        WordList &keywords3 = *keywordlists[2];
 
70
        WordList &keywords4 = *keywordlists[3];
 
71
        WordList &keywords5 = *keywordlists[4];
 
72
        WordList &keywords6 = *keywordlists[5];
 
73
        WordList &keywords7 = *keywordlists[6];
 
74
        WordList &keywords8 = *keywordlists[7];
 
75
 
 
76
        int currentLine = styler.GetLine(startPos);
 
77
        // Initialize the braced string {.. { ... } ..} nesting level, if we are inside such a string.
 
78
        int stringLevel = 0;
 
79
        if (initStyle == SCE_REBOL_BRACEDSTRING || initStyle == SCE_REBOL_COMMENTBLOCK) {
 
80
                stringLevel = styler.GetLineState(currentLine - 1);
 
81
        }
 
82
 
 
83
        bool blockComment = initStyle == SCE_REBOL_COMMENTBLOCK;
 
84
        int dotCount = 0;
 
85
 
 
86
        // Do not leak onto next line
 
87
        if (initStyle == SCE_REBOL_COMMENTLINE) {
 
88
                initStyle = SCE_REBOL_DEFAULT;
 
89
        }
 
90
 
 
91
        StyleContext sc(startPos, length, initStyle, styler);
 
92
        if (startPos == 0) {
 
93
                sc.SetState(SCE_REBOL_PREFACE);
 
94
        }
 
95
        for (; sc.More(); sc.Forward()) {
 
96
 
 
97
                //--- What to do at line end ?
 
98
                if (sc.atLineEnd) {
 
99
                        // Can be either inside a {} string or simply at eol
 
100
                        if (sc.state != SCE_REBOL_BRACEDSTRING && sc.state != SCE_REBOL_COMMENTBLOCK &&
 
101
                                sc.state != SCE_REBOL_BINARY && sc.state != SCE_REBOL_PREFACE)
 
102
                                sc.SetState(SCE_REBOL_DEFAULT);
 
103
 
 
104
                        // Update the line state, so it can be seen by next line
 
105
                        currentLine = styler.GetLine(sc.currentPos);
 
106
                        switch (sc.state) {
 
107
                        case SCE_REBOL_BRACEDSTRING:
 
108
                        case SCE_REBOL_COMMENTBLOCK:
 
109
                                // Inside a braced string, we set the line state
 
110
                                styler.SetLineState(currentLine, stringLevel);
 
111
                                break;
 
112
                        default:
 
113
                                // Reset the line state
 
114
                                styler.SetLineState(currentLine, 0);
 
115
                                break;
 
116
                        }
 
117
 
 
118
                        // continue with next char
 
119
                        continue;
 
120
                }
 
121
 
 
122
                //--- What to do on white-space ?
 
123
                if (IsASpaceOrTab(sc.ch))
 
124
                {
 
125
                        // Return to default if any of these states
 
126
                        if (sc.state == SCE_REBOL_OPERATOR || sc.state == SCE_REBOL_CHARACTER ||
 
127
                                sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR ||
 
128
                                sc.state == SCE_REBOL_TUPLE || sc.state == SCE_REBOL_FILE ||
 
129
                                sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME ||
 
130
                                sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE ||
 
131
                                sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_EMAIL) {
 
132
                                sc.SetState(SCE_REBOL_DEFAULT);
 
133
                        }
 
134
                }
 
135
 
 
136
                //--- Specialize state ?
 
137
                // URL, Email look like identifier
 
138
                if (sc.state == SCE_REBOL_IDENTIFIER)
 
139
                {
 
140
                        if (sc.ch == ':' && !IsASpace(sc.chNext)) {
 
141
                                sc.ChangeState(SCE_REBOL_URL);
 
142
                        } else if (sc.ch == '@') {
 
143
                                sc.ChangeState(SCE_REBOL_EMAIL);
 
144
                        } else if (sc.ch == '$') {
 
145
                                sc.ChangeState(SCE_REBOL_MONEY);
 
146
                        }
 
147
                }
 
148
                // Words look like identifiers
 
149
                if (sc.state == SCE_REBOL_IDENTIFIER || (sc.state >= SCE_REBOL_WORD && sc.state <= SCE_REBOL_WORD8)) {
 
150
                        // Keywords ?
 
151
                        if (!IsAWordChar(sc.ch) || sc.Match('/')) {
 
152
                                char s[100];
 
153
                                sc.GetCurrentLowered(s, sizeof(s));
 
154
                                blockComment = strcmp(s, "comment") == 0;
 
155
                                if (keywords8.InList(s)) {
 
156
                                        sc.ChangeState(SCE_REBOL_WORD8);
 
157
                                } else if (keywords7.InList(s)) {
 
158
                                        sc.ChangeState(SCE_REBOL_WORD7);
 
159
                                } else if (keywords6.InList(s)) {
 
160
                                        sc.ChangeState(SCE_REBOL_WORD6);
 
161
                                } else if (keywords5.InList(s)) {
 
162
                                        sc.ChangeState(SCE_REBOL_WORD5);
 
163
                                } else if (keywords4.InList(s)) {
 
164
                                        sc.ChangeState(SCE_REBOL_WORD4);
 
165
                                } else if (keywords3.InList(s)) {
 
166
                                        sc.ChangeState(SCE_REBOL_WORD3);
 
167
                                } else if (keywords2.InList(s)) {
 
168
                                        sc.ChangeState(SCE_REBOL_WORD2);
 
169
                                } else if (keywords.InList(s)) {
 
170
                                        sc.ChangeState(SCE_REBOL_WORD);
 
171
                                }
 
172
                                // Keep same style if there are refinements
 
173
                                if (!sc.Match('/')) {
 
174
                                        sc.SetState(SCE_REBOL_DEFAULT);
 
175
                                }
 
176
                        }
 
177
                // special numbers
 
178
                } else if (sc.state == SCE_REBOL_NUMBER) {
 
179
                        switch (sc.ch) {
 
180
                        case 'x':       sc.ChangeState(SCE_REBOL_PAIR);
 
181
                                                break;
 
182
                        case ':':       sc.ChangeState(SCE_REBOL_TIME);
 
183
                                                break;
 
184
                        case '-':
 
185
                        case '/':       sc.ChangeState(SCE_REBOL_DATE);
 
186
                                                break;
 
187
                        case '.':       if (++dotCount >= 2) sc.ChangeState(SCE_REBOL_TUPLE);
 
188
                                                break;
 
189
                        }
 
190
                }
 
191
 
 
192
                //--- Determine if the current state should terminate
 
193
                if (sc.state == SCE_REBOL_QUOTEDSTRING || sc.state == SCE_REBOL_CHARACTER) {
 
194
                        if (sc.ch == '^' && sc.chNext == '\"') {
 
195
                                sc.Forward();
 
196
                        } else if (sc.ch == '\"') {
 
197
                                sc.ForwardSetState(SCE_REBOL_DEFAULT);
 
198
                        }
 
199
                } else if (sc.state == SCE_REBOL_BRACEDSTRING || sc.state == SCE_REBOL_COMMENTBLOCK) {
 
200
                        if (sc.ch == '}') {
 
201
                                if (--stringLevel == 0) {
 
202
                                        sc.ForwardSetState(SCE_REBOL_DEFAULT);
 
203
                                }
 
204
                        } else if (sc.ch == '{') {
 
205
                                stringLevel++;
 
206
                        }
 
207
                } else if (sc.state == SCE_REBOL_BINARY) {
 
208
                        if (sc.ch == '}') {
 
209
                                sc.ForwardSetState(SCE_REBOL_DEFAULT);
 
210
                        }
 
211
                } else if (sc.state == SCE_REBOL_TAG) {
 
212
                        if (sc.ch == '>') {
 
213
                                sc.ForwardSetState(SCE_REBOL_DEFAULT);
 
214
                        }
 
215
                } else if (sc.state == SCE_REBOL_PREFACE) {
 
216
                        if (sc.MatchIgnoreCase("rebol"))
 
217
                        {
 
218
                                int i;
 
219
                                for (i=5; IsASpaceOrTab(styler.SafeGetCharAt(sc.currentPos+i, 0)); i++);
 
220
                                if (sc.GetRelative(i) == '[')
 
221
                                        sc.SetState(SCE_REBOL_DEFAULT);
 
222
                        }
 
223
                }
 
224
 
 
225
                //--- Parens and bracket changes to default style when the current is a number
 
226
                if (sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR || sc.state == SCE_REBOL_TUPLE ||
 
227
                        sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE || sc.state == SCE_REBOL_EMAIL ||
 
228
                        sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME) {
 
229
                        if (sc.ch == '(' || sc.ch == '[' || sc.ch == ')' || sc.ch == ']') {
 
230
                                sc.SetState(SCE_REBOL_DEFAULT);
 
231
                        }
 
232
                }
 
233
 
 
234
                //--- Determine if a new state should be entered.
 
235
                if (sc.state == SCE_REBOL_DEFAULT) {
 
236
                        if (IsAnOperator(sc.ch, sc.chNext, sc.GetRelative(2))) {
 
237
                                sc.SetState(SCE_REBOL_OPERATOR);
 
238
                        } else if (IsBinaryStart(sc.ch, sc.chNext, sc.GetRelative(2), sc.GetRelative(3))) {
 
239
                                sc.SetState(SCE_REBOL_BINARY);
 
240
                        } else if (IsAWordStart(sc.ch, sc.chNext)) {
 
241
                                sc.SetState(SCE_REBOL_IDENTIFIER);
 
242
                        } else if (IsADigit(sc.ch) || sc.ch == '+' || sc.ch == '-' || /*Decimal*/ sc.ch == '.' || sc.ch == ',') {
 
243
                                dotCount = 0;
 
244
                                sc.SetState(SCE_REBOL_NUMBER);
 
245
                        } else if (sc.ch == '\"') {
 
246
                                sc.SetState(SCE_REBOL_QUOTEDSTRING);
 
247
                        } else if (sc.ch == '{') {
 
248
                                sc.SetState(blockComment ? SCE_REBOL_COMMENTBLOCK : SCE_REBOL_BRACEDSTRING);
 
249
                                ++stringLevel;
 
250
                        } else if (sc.ch == ';') {
 
251
                                sc.SetState(SCE_REBOL_COMMENTLINE);
 
252
                        } else if (sc.ch == '$') {
 
253
                                sc.SetState(SCE_REBOL_MONEY);
 
254
                        } else if (sc.ch == '%') {
 
255
                                sc.SetState(SCE_REBOL_FILE);
 
256
                        } else if (sc.ch == '<') {
 
257
                                sc.SetState(SCE_REBOL_TAG);
 
258
                        } else if (sc.ch == '#' && sc.chNext == '"') {
 
259
                                sc.SetState(SCE_REBOL_CHARACTER);
 
260
                                sc.Forward();
 
261
                        } else if (sc.ch == '#' && sc.chNext != '"' && sc.chNext != '{' ) {
 
262
                                sc.SetState(SCE_REBOL_ISSUE);
 
263
                        }
 
264
                }
 
265
        }
 
266
        sc.Complete();
 
267
}
 
268
 
 
269
 
 
270
static void FoldRebolDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[],
 
271
                            Accessor &styler) {
 
272
        unsigned int lengthDoc = startPos + length;
 
273
        int visibleChars = 0;
 
274
        int lineCurrent = styler.GetLine(startPos);
 
275
        int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
 
276
        int levelCurrent = levelPrev;
 
277
        char chNext = styler[startPos];
 
278
        int styleNext = styler.StyleAt(startPos);
 
279
        for (unsigned int i = startPos; i < lengthDoc; i++) {
 
280
                char ch = chNext;
 
281
                chNext = styler.SafeGetCharAt(i + 1);
 
282
                int style = styleNext;
 
283
                styleNext = styler.StyleAt(i + 1);
 
284
                bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 
285
                if (style == SCE_REBOL_DEFAULT) {
 
286
                        if (ch == '[') {
 
287
                                levelCurrent++;
 
288
                        } else if (ch == ']') {
 
289
                                levelCurrent--;
 
290
                        }
 
291
                }
 
292
                if (atEOL) {
 
293
                        int lev = levelPrev;
 
294
                        if (visibleChars == 0)
 
295
                                lev |= SC_FOLDLEVELWHITEFLAG;
 
296
                        if ((levelCurrent > levelPrev) && (visibleChars > 0))
 
297
                                lev |= SC_FOLDLEVELHEADERFLAG;
 
298
                        if (lev != styler.LevelAt(lineCurrent)) {
 
299
                                styler.SetLevel(lineCurrent, lev);
 
300
                        }
 
301
                        lineCurrent++;
 
302
                        levelPrev = levelCurrent;
 
303
                        visibleChars = 0;
 
304
                }
 
305
                if (!isspacechar(ch))
 
306
                        visibleChars++;
 
307
        }
 
308
        // Fill in the real level of the next line, keeping the current flags as they will be filled in later
 
309
        int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
 
310
        styler.SetLevel(lineCurrent, levelPrev | flagsNext);
 
311
}
 
312
 
 
313
static const char * const rebolWordListDesc[] = {
 
314
        "Keywords",
 
315
        0
 
316
};
 
317
 
 
318
LexerModule lmREBOL(SCLEX_REBOL, ColouriseRebolDoc, "rebol", FoldRebolDoc, rebolWordListDesc);
 
319