]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexPascal.cxx
491d968ac99743bfa9404ab64056d5ceeaf5d7ce
[wxWidgets.git] / src / stc / scintilla / src / LexPascal.cxx
1 // Scintilla source code edit control
2 /** @file LexPascal.cxx
3 ** Lexer for Pascal.
4 ** Written by Laurent le Tynevez
5 **/
6
7 #include <stdlib.h>
8 #include <string.h>
9 #include <ctype.h>
10 #include <stdio.h>
11 #include <stdarg.h>
12
13 #include "Platform.h"
14
15 #include "PropSet.h"
16 #include "Accessor.h"
17 #include "KeyWords.h"
18 #include "Scintilla.h"
19 #include "SciLexer.h"
20
21 static int classifyWordPascal(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
22 char s[100];
23 for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
24 s[i] = static_cast<char>(tolower(styler[start + i]));
25 s[i + 1] = '\0';
26 }
27 int lev= 0;
28 char chAttr = SCE_C_IDENTIFIER;
29 if (isdigit(s[0]) || (s[0] == '.')){
30 chAttr = SCE_C_NUMBER;
31 }
32 else {
33 if (keywords.InList(s)) {
34 chAttr = SCE_C_WORD;
35 if (strcmp(s, "begin") == 0 || strcmp(s, "object") == 0)
36 lev=1;
37 else if (strcmp(s, "end") == 0)
38 lev=-1;
39 }
40 }
41 styler.ColourTo(end, chAttr);
42 return lev;
43 }
44
45 static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
46 Accessor &styler) {
47 WordList &keywords = *keywordlists[0];
48
49 styler.StartAt(startPos);
50
51 bool fold = styler.GetPropertyInt("fold") != 0;
52 int lineCurrent = styler.GetLine(startPos);
53 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
54 int levelCurrent = levelPrev;
55
56 int state = initStyle;
57 if (state == SCE_C_STRINGEOL) // Does not leak onto next line
58 state = SCE_C_DEFAULT;
59 char chPrev = ' ';
60 char chNext = styler[startPos];
61 unsigned int lengthDoc = startPos + length;
62 int visibleChars = 0;
63 styler.StartSegment(startPos);
64 for (unsigned int i = startPos; i < lengthDoc; i++) {
65 char ch = chNext;
66 chNext = styler.SafeGetCharAt(i + 1);
67
68 if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
69 // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
70 // Avoid triggering two times on Dos/Win
71 // End of line
72 if (state == SCE_C_STRINGEOL) {
73 styler.ColourTo(i, state);
74 state = SCE_C_DEFAULT;
75 }
76 if (fold) {
77 int lev = levelPrev;
78 if (visibleChars == 0)
79 lev |= SC_FOLDLEVELWHITEFLAG;
80 if ((levelCurrent > levelPrev) && (visibleChars > 0))
81 lev |= SC_FOLDLEVELHEADERFLAG;
82 styler.SetLevel(lineCurrent, lev);
83 lineCurrent++;
84 levelPrev = levelCurrent;
85 }
86 visibleChars = 0;
87 }
88 if (!isspacechar(ch))
89 visibleChars++;
90
91 if (styler.IsLeadByte(ch)) {
92 chNext = styler.SafeGetCharAt(i + 2);
93 chPrev = ' ';
94 i += 1;
95 continue;
96 }
97
98 if (state == SCE_C_DEFAULT) {
99 if (iswordstart(ch) || (ch == '@')) {
100 styler.ColourTo(i-1, state);
101 state = SCE_C_IDENTIFIER;
102 } else if (ch == '{' && chNext != '$' && chNext != '&') {
103 styler.ColourTo(i-1, state);
104 state = SCE_C_COMMENT;
105 } else if (ch == '(' && chNext == '*'
106 && styler.SafeGetCharAt(i + 2) != '$'
107 && styler.SafeGetCharAt(i + 2) != '&') {
108 styler.ColourTo(i-1, state);
109 state = SCE_C_COMMENTDOC;
110 } else if (ch == '/' && chNext == '/') {
111 styler.ColourTo(i-1, state);
112 state = SCE_C_COMMENTLINE;
113 } else if (ch == '\"') {
114 styler.ColourTo(i-1, state);
115 state = SCE_C_STRING;
116 } else if (ch == '\'') {
117 styler.ColourTo(i-1, state);
118 state = SCE_C_CHARACTER;
119 } else if (ch == '{' && (chNext == '$' || chNext=='&') && visibleChars == 1) {
120 styler.ColourTo(i-1, state);
121 state = SCE_C_PREPROCESSOR;
122 } else if (isoperator(ch)) {
123 styler.ColourTo(i-1, state);
124 styler.ColourTo(i, SCE_C_OPERATOR);
125
126 }
127 } else if (state == SCE_C_IDENTIFIER) {
128 if (!iswordchar(ch)) {
129 int levelChange = classifyWordPascal(styler.GetStartSegment(), i - 1, keywords, styler);
130 state = SCE_C_DEFAULT;
131 chNext = styler.SafeGetCharAt(i + 1);
132 if (ch == '{' && chNext != '$' && chNext != '&') {
133 state = SCE_C_COMMENT;
134 } else if (ch == '(' && chNext == '*'
135 && styler.SafeGetCharAt(i + 2) != '$'
136 && styler.SafeGetCharAt(i + 2) != '&') {
137 styler.ColourTo(i-1, state);
138 state = SCE_C_COMMENTDOC;
139 } else if (ch == '/' && chNext == '/') {
140 state = SCE_C_COMMENTLINE;
141 } else if (ch == '\"') {
142 state = SCE_C_STRING;
143 } else if (ch == '\'') {
144 state = SCE_C_CHARACTER;
145 } else if (isoperator(ch)) {
146 styler.ColourTo(i, SCE_C_OPERATOR);
147 }
148 levelCurrent+=levelChange;
149 }
150 } else {
151 if (state == SCE_C_PREPROCESSOR) {
152 if (ch=='}'){
153 styler.ColourTo(i, state);
154 state = SCE_C_DEFAULT;
155 } else {
156 if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
157 styler.ColourTo(i-1, state);
158 state = SCE_C_DEFAULT;
159 }
160 }
161 } else if (state == SCE_C_COMMENT) {
162 if (ch == '}' ) {
163 styler.ColourTo(i, state);
164 state = SCE_C_DEFAULT;
165 }
166 } else if (state == SCE_C_COMMENTDOC) {
167 if (ch == ')' && chPrev == '*') {
168 if (((i > styler.GetStartSegment() + 2) || (
169 (initStyle == SCE_C_COMMENTDOC) &&
170 (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
171 styler.ColourTo(i, state);
172 state = SCE_C_DEFAULT;
173 }
174 }
175 } else if (state == SCE_C_COMMENTLINE) {
176 if (ch == '\r' || ch == '\n') {
177 styler.ColourTo(i-1, state);
178 state = SCE_C_DEFAULT;
179 }
180 } else if (state == SCE_C_STRING) {
181 if (ch == '\\') {
182 if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
183 i++;
184 ch = chNext;
185 chNext = styler.SafeGetCharAt(i + 1);
186 }
187 } else if (ch == '\"') {
188 styler.ColourTo(i, state);
189 state = SCE_C_DEFAULT;
190 } else if (chNext == '\r' || chNext == '\n') {
191 styler.ColourTo(i-1, SCE_C_STRINGEOL);
192 state = SCE_C_STRINGEOL;
193 }
194 } else if (state == SCE_C_CHARACTER) {
195 if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) {
196 styler.ColourTo(i-1, SCE_C_STRINGEOL);
197 state = SCE_C_STRINGEOL;
198 } else if (ch == '\\') {
199 if (chNext == '\"' || chNext == '\'' || chNext == '\\') {
200 i++;
201 ch = chNext;
202 chNext = styler.SafeGetCharAt(i + 1);
203 }
204 } else if (ch == '\'') {
205 styler.ColourTo(i, state);
206 state = SCE_C_DEFAULT;
207 }
208 }
209 }
210 chPrev = ch;
211 }
212 styler.ColourTo(lengthDoc - 1, state);
213
214 // Fill in the real level of the next line, keeping the current flags as they will be filled in later
215 if (fold) {
216 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
217 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
218 }
219 }
220
221 LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal");