116 |
116 |
ClearBraces();
|
117 |
117 |
}
|
118 |
118 |
|
119 |
|
void CodeEditor::SyntaxState::ScanSyntax(const wchar *ln, const wchar *e)
|
|
119 |
void CodeEditor::SyntaxState::ScanSyntax(const wchar *ln, const wchar *e, const int highlight)
|
120 |
120 |
{
|
121 |
121 |
Grounding(ln, e);
|
122 |
122 |
if(!linecont) {
|
... | ... | |
138 |
138 |
uvscolor = c;
|
139 |
139 |
p += n;
|
140 |
140 |
}
|
141 |
|
if(!comment && *p == '#') {
|
142 |
|
while(++p < e && (*p == ' ' || *p == '\t'))
|
143 |
|
p++;
|
144 |
|
const wchar *id = p;
|
145 |
|
while(p < e && iscidl(*p))
|
146 |
|
p++;
|
147 |
|
int idlen = int(p - id);
|
148 |
|
if(id[0] == 'i' && id[1] == 'f'
|
149 |
|
&& (idlen == 2 || idlen == 5 && id[2] == 'd' && id[3] == 'e' && id[4] == 'f'
|
150 |
|
|| idlen == 6 && id[2] == 'n' && id[3] == 'd' && id[4] == 'e' && id[5] == 'f')) {
|
151 |
|
IfState& ifstate = ifstack.Add();
|
152 |
|
ifstate.state = IfState::IF;
|
153 |
|
ifstate.iftext = sReadLn(ln);
|
154 |
|
ifstate.ifline = line + 1;
|
|
141 |
if(highlight == HIGHLIGHT_SH) {
|
|
142 |
for(;;) {
|
|
143 |
if(p >= e) return;
|
|
144 |
const wchar *pp;
|
|
145 |
int c = *p++;
|
|
146 |
if(c == '#') {
|
|
147 |
linecomment = true;
|
|
148 |
return;
|
|
149 |
}
|
|
150 |
else
|
|
151 |
if(c == '\'' || c == '\"') {
|
|
152 |
p = eatstring(p - 1);
|
|
153 |
if(p >= e) {
|
|
154 |
string = true;
|
|
155 |
return;
|
|
156 |
}
|
|
157 |
}
|
|
158 |
else
|
|
159 |
if(c == '{') {
|
|
160 |
if(was_namespace) {
|
|
161 |
brk.Add(0);
|
|
162 |
was_namespace = false;
|
|
163 |
}
|
|
164 |
else {
|
|
165 |
cl++;
|
|
166 |
brk.Add('}');
|
|
167 |
bid.Add(lindent + 1);
|
|
168 |
}
|
|
169 |
blk.Add() = line;
|
|
170 |
stmtline = -1;
|
|
171 |
par.Clear();
|
|
172 |
}
|
|
173 |
else
|
|
174 |
if(c == '}') {
|
|
175 |
if(brk.GetCount()) {
|
|
176 |
if(brk.Top()) {
|
|
177 |
cl--;
|
|
178 |
if(bid.GetCount() > 1)
|
|
179 |
bid.Drop();
|
|
180 |
}
|
|
181 |
brk.Drop();
|
|
182 |
}
|
|
183 |
if(blk.GetCount())
|
|
184 |
blk.Drop();
|
|
185 |
stmtline = -1;
|
|
186 |
par.Clear();
|
|
187 |
}
|
|
188 |
else
|
|
189 |
if(c == '(') {
|
|
190 |
pl++;
|
|
191 |
brk.Add(')');
|
|
192 |
Isx& m = par.Add();
|
|
193 |
m.line = line;
|
|
194 |
m.pos = int(p - ln);
|
|
195 |
spar++;
|
|
196 |
}
|
|
197 |
else
|
|
198 |
if(c == '[') {
|
|
199 |
bl++;
|
|
200 |
brk.Add(']');
|
|
201 |
Isx& m = par.Add();
|
|
202 |
m.line = line;
|
|
203 |
m.pos = int(p - ln);
|
|
204 |
spar++;
|
|
205 |
}
|
|
206 |
else
|
|
207 |
if(c == ')') {
|
|
208 |
if(brk.GetCount()) {
|
|
209 |
pl--;
|
|
210 |
brk.Drop();
|
|
211 |
}
|
|
212 |
if(par.GetCount())
|
|
213 |
par.Drop();
|
|
214 |
spar--;
|
|
215 |
}
|
|
216 |
else
|
|
217 |
if(c == ']') {
|
|
218 |
if(brk.GetCount()) {
|
|
219 |
bl--;
|
|
220 |
brk.Drop();
|
|
221 |
}
|
|
222 |
if(par.GetCount())
|
|
223 |
par.Drop();
|
|
224 |
spar--;
|
|
225 |
}
|
155 |
226 |
}
|
156 |
|
switch(idlen)
|
157 |
|
{
|
158 |
|
case 6:
|
159 |
|
if(id[0] == 'd' && id[1] == 'e' && id[2] == 'f' && id[3] == 'i' && id[4] == 'n' && id[5] == 'e')
|
160 |
|
macro = SyntaxState::MACRO_CONT;
|
161 |
|
break;
|
162 |
|
|
163 |
|
case 4:
|
164 |
|
if(id[0] == 'e' && id[1] == 'l')
|
165 |
|
if(id[2] == 'i' && id[3] == 'f')
|
166 |
|
if(ifstack.GetCount() == 0) {
|
167 |
|
IfState& ifstate = ifstack.Add();
|
168 |
|
ifstate.ifline = 0;
|
169 |
|
ifstate.state = IfState::ELSE_ERROR;
|
170 |
|
}
|
171 |
|
else {
|
172 |
|
IfState& ifstate = ifstack.Top();
|
173 |
|
if(ifstate.state == IfState::IF || ifstate.state == IfState::ELIF) {
|
174 |
|
ifstate.state = IfState::ELIF;
|
175 |
|
ifstate.iftext = WString().Cat() << sReadLn(ln) << ", " << ifstate.iftext;
|
|
227 |
} else {
|
|
228 |
if(!comment && *p == '#') {
|
|
229 |
while(++p < e && (*p == ' ' || *p == '\t'))
|
|
230 |
p++;
|
|
231 |
const wchar *id = p;
|
|
232 |
while(p < e && iscidl(*p))
|
|
233 |
p++;
|
|
234 |
int idlen = int(p - id);
|
|
235 |
if(id[0] == 'i' && id[1] == 'f'
|
|
236 |
&& (idlen == 2 || idlen == 5 && id[2] == 'd' && id[3] == 'e' && id[4] == 'f'
|
|
237 |
|| idlen == 6 && id[2] == 'n' && id[3] == 'd' && id[4] == 'e' && id[5] == 'f')) {
|
|
238 |
IfState& ifstate = ifstack.Add();
|
|
239 |
ifstate.state = IfState::IF;
|
|
240 |
ifstate.iftext = sReadLn(ln);
|
|
241 |
ifstate.ifline = line + 1;
|
|
242 |
}
|
|
243 |
switch(idlen)
|
|
244 |
{
|
|
245 |
case 6:
|
|
246 |
if(id[0] == 'd' && id[1] == 'e' && id[2] == 'f' && id[3] == 'i' && id[4] == 'n' && id[5] == 'e')
|
|
247 |
macro = SyntaxState::MACRO_CONT;
|
|
248 |
break;
|
|
249 |
|
|
250 |
case 4:
|
|
251 |
if(id[0] == 'e' && id[1] == 'l')
|
|
252 |
if(id[2] == 'i' && id[3] == 'f')
|
|
253 |
if(ifstack.GetCount() == 0) {
|
|
254 |
IfState& ifstate = ifstack.Add();
|
|
255 |
ifstate.ifline = 0;
|
|
256 |
ifstate.state = IfState::ELSE_ERROR;
|
176 |
257 |
}
|
177 |
|
else
|
|
258 |
else {
|
|
259 |
IfState& ifstate = ifstack.Top();
|
|
260 |
if(ifstate.state == IfState::IF || ifstate.state == IfState::ELIF) {
|
|
261 |
ifstate.state = IfState::ELIF;
|
|
262 |
ifstate.iftext = WString().Cat() << sReadLn(ln) << ", " << ifstate.iftext;
|
|
263 |
}
|
|
264 |
else
|
|
265 |
ifstate.state = IfState::ELSE_ERROR;
|
|
266 |
}
|
|
267 |
else
|
|
268 |
if(id[2] == 's' && id[3] == 'e')
|
|
269 |
if(ifstack.GetCount() == 0) {
|
|
270 |
IfState& ifstate = ifstack.Add();
|
|
271 |
ifstate.ifline = 0;
|
178 |
272 |
ifstate.state = IfState::ELSE_ERROR;
|
179 |
|
}
|
180 |
|
else
|
181 |
|
if(id[2] == 's' && id[3] == 'e')
|
182 |
|
if(ifstack.GetCount() == 0) {
|
|
273 |
}
|
|
274 |
else {
|
|
275 |
IfState& ifstate = ifstack.Top();
|
|
276 |
if(ifstate.state == IfState::IF || ifstate.state == IfState::ELIF) {
|
|
277 |
ifstate.state = IfState::ELSE;
|
|
278 |
ifstate.iftext = "#else, " + ifstate.iftext;
|
|
279 |
}
|
|
280 |
else
|
|
281 |
ifstate.state = IfState::ELSE_ERROR;
|
|
282 |
}
|
|
283 |
break;
|
|
284 |
|
|
285 |
case 5:
|
|
286 |
if(id[0] == 'e' && id[1] == 'n' && id[2] == 'd' && id[3] == 'i' && id[4] == 'f')
|
|
287 |
{
|
|
288 |
int itop = ifstack.GetCount() - 1;
|
|
289 |
if(itop < 0) {
|
183 |
290 |
IfState& ifstate = ifstack.Add();
|
184 |
291 |
ifstate.ifline = 0;
|
185 |
|
ifstate.state = IfState::ELSE_ERROR;
|
|
292 |
ifstate.state = IfState::ENDIF_ERROR;
|
186 |
293 |
}
|
187 |
|
else {
|
188 |
|
IfState& ifstate = ifstack.Top();
|
189 |
|
if(ifstate.state == IfState::IF || ifstate.state == IfState::ELIF) {
|
190 |
|
ifstate.state = IfState::ELSE;
|
191 |
|
ifstate.iftext = "#else, " + ifstate.iftext;
|
192 |
|
}
|
193 |
|
else
|
194 |
|
ifstate.state = IfState::ELSE_ERROR;
|
195 |
|
}
|
196 |
|
break;
|
197 |
|
|
198 |
|
case 5:
|
199 |
|
if(id[0] == 'e' && id[1] == 'n' && id[2] == 'd' && id[3] == 'i' && id[4] == 'f')
|
200 |
|
{
|
201 |
|
int itop = ifstack.GetCount() - 1;
|
202 |
|
if(itop < 0) {
|
203 |
|
IfState& ifstate = ifstack.Add();
|
204 |
|
ifstate.ifline = 0;
|
205 |
|
ifstate.state = IfState::ENDIF_ERROR;
|
|
294 |
else if(ifstack[itop].state != IfState::ENDIF_ERROR)
|
|
295 |
ifstack.Trim(itop);
|
206 |
296 |
}
|
207 |
|
else if(ifstack[itop].state != IfState::ENDIF_ERROR)
|
208 |
|
ifstack.Trim(itop);
|
|
297 |
break;
|
209 |
298 |
}
|
210 |
|
break;
|
211 |
299 |
}
|
212 |
|
}
|
213 |
|
if(macro == SyntaxState::MACRO_CONT && !(p < e && e[-1] == '\\'))
|
214 |
|
macro = SyntaxState::MACRO_END;
|
215 |
|
for(;;) {
|
216 |
|
if(comment) {
|
217 |
|
p = strnext(p, e, '*');
|
218 |
|
if(!p) break;
|
219 |
|
if(*++p == '/') {
|
220 |
|
comment = false;
|
221 |
|
p++;
|
|
300 |
if(macro == SyntaxState::MACRO_CONT && !(p < e && e[-1] == '\\'))
|
|
301 |
macro = SyntaxState::MACRO_END;
|
|
302 |
for(;;) {
|
|
303 |
if(comment) {
|
|
304 |
p = strnext(p, e, '*');
|
|
305 |
if(!p) break;
|
|
306 |
if(*++p == '/') {
|
|
307 |
comment = false;
|
|
308 |
p++;
|
|
309 |
}
|
222 |
310 |
}
|
223 |
|
}
|
224 |
|
else {
|
225 |
|
int pc = 0;
|
226 |
|
for(;;) {
|
227 |
|
if(p >= e) return;
|
228 |
|
const wchar *pp;
|
229 |
|
if(!iscidl(pc) && (pp = isstmt(p)) != NULL) {
|
230 |
|
stmtline = line;
|
231 |
|
spar = 0;
|
232 |
|
pc = 0;
|
233 |
|
p = pp;
|
234 |
|
}
|
235 |
|
else
|
236 |
|
if(!iscidl(pc) && p[0] == 'n' && p[1] == 'a' && p[2] == 'm' && p[3] == 'e' &&
|
237 |
|
p[4] == 's' && p[5] == 'p' && p[6] == 'a' && p[7] == 'c' && p[8] == 'e' &&
|
238 |
|
!iscidl(p[9])) {
|
239 |
|
was_namespace = true;
|
240 |
|
p += 9;
|
241 |
|
}
|
242 |
|
else {
|
243 |
|
int c = *p++;
|
244 |
|
if(c == '/') break;
|
245 |
|
if(c == '\'' || c == '\"') {
|
246 |
|
p = eatstring(p - 1);
|
247 |
|
if(p >= e) {
|
248 |
|
string = true;
|
249 |
|
return;
|
250 |
|
}
|
|
311 |
else {
|
|
312 |
int pc = 0;
|
|
313 |
for(;;) {
|
|
314 |
if(p >= e) return;
|
|
315 |
const wchar *pp;
|
|
316 |
if(!iscidl(pc) && (pp = isstmt(p)) != NULL) {
|
|
317 |
stmtline = line;
|
|
318 |
spar = 0;
|
|
319 |
pc = 0;
|
|
320 |
p = pp;
|
251 |
321 |
}
|
252 |
322 |
else
|
253 |
|
if(c == ';' && spar == 0) {
|
254 |
|
seline = stmtline;
|
255 |
|
endstmtline = line;
|
256 |
|
stmtline = -1;
|
257 |
|
was_namespace = false;
|
|
323 |
if(!iscidl(pc) && p[0] == 'n' && p[1] == 'a' && p[2] == 'm' && p[3] == 'e' &&
|
|
324 |
p[4] == 's' && p[5] == 'p' && p[6] == 'a' && p[7] == 'c' && p[8] == 'e' &&
|
|
325 |
!iscidl(p[9])) {
|
|
326 |
was_namespace = true;
|
|
327 |
p += 9;
|
258 |
328 |
}
|
259 |
|
else
|
260 |
|
if(c == '{') {
|
261 |
|
if(was_namespace) {
|
262 |
|
brk.Add(0);
|
|
329 |
else {
|
|
330 |
int c = *p++;
|
|
331 |
if(c == '/') break;
|
|
332 |
if(c == '\'' || c == '\"') {
|
|
333 |
p = eatstring(p - 1);
|
|
334 |
if(p >= e) {
|
|
335 |
string = true;
|
|
336 |
return;
|
|
337 |
}
|
|
338 |
}
|
|
339 |
else
|
|
340 |
if(c == ';' && spar == 0) {
|
|
341 |
seline = stmtline;
|
|
342 |
endstmtline = line;
|
|
343 |
stmtline = -1;
|
263 |
344 |
was_namespace = false;
|
264 |
345 |
}
|
265 |
|
else {
|
266 |
|
cl++;
|
267 |
|
brk.Add('}');
|
268 |
|
bid.Add(lindent + 1);
|
|
346 |
else
|
|
347 |
if(c == '{') {
|
|
348 |
if(was_namespace) {
|
|
349 |
brk.Add(0);
|
|
350 |
was_namespace = false;
|
|
351 |
}
|
|
352 |
else {
|
|
353 |
cl++;
|
|
354 |
brk.Add('}');
|
|
355 |
bid.Add(lindent + 1);
|
|
356 |
}
|
|
357 |
blk.Add() = line;
|
|
358 |
stmtline = -1;
|
|
359 |
par.Clear();
|
269 |
360 |
}
|
270 |
|
blk.Add() = line;
|
271 |
|
stmtline = -1;
|
272 |
|
par.Clear();
|
273 |
|
}
|
274 |
|
else
|
275 |
|
if(c == '}') {
|
276 |
|
if(brk.GetCount()) {
|
277 |
|
if(brk.Top()) {
|
278 |
|
cl--;
|
279 |
|
if(bid.GetCount() > 1)
|
280 |
|
bid.Drop();
|
|
361 |
else
|
|
362 |
if(c == '}') {
|
|
363 |
if(brk.GetCount()) {
|
|
364 |
if(brk.Top()) {
|
|
365 |
cl--;
|
|
366 |
if(bid.GetCount() > 1)
|
|
367 |
bid.Drop();
|
|
368 |
}
|
|
369 |
brk.Drop();
|
281 |
370 |
}
|
282 |
|
brk.Drop();
|
|
371 |
if(blk.GetCount())
|
|
372 |
blk.Drop();
|
|
373 |
stmtline = -1;
|
|
374 |
par.Clear();
|
283 |
375 |
}
|
284 |
|
if(blk.GetCount())
|
285 |
|
blk.Drop();
|
286 |
|
stmtline = -1;
|
287 |
|
par.Clear();
|
288 |
|
}
|
289 |
|
else
|
290 |
|
if(c == '(') {
|
291 |
|
pl++;
|
292 |
|
brk.Add(')');
|
293 |
|
Isx& m = par.Add();
|
294 |
|
m.line = line;
|
295 |
|
m.pos = int(p - ln);
|
296 |
|
spar++;
|
297 |
|
}
|
298 |
|
else
|
299 |
|
if(c == '[') {
|
300 |
|
bl++;
|
301 |
|
brk.Add(']');
|
302 |
|
Isx& m = par.Add();
|
303 |
|
m.line = line;
|
304 |
|
m.pos = int(p - ln);
|
305 |
|
spar++;
|
306 |
|
}
|
307 |
|
else
|
308 |
|
if(c == ')') {
|
309 |
|
if(brk.GetCount()) {
|
310 |
|
pl--;
|
311 |
|
brk.Drop();
|
|
376 |
else
|
|
377 |
if(c == '(') {
|
|
378 |
pl++;
|
|
379 |
brk.Add(')');
|
|
380 |
Isx& m = par.Add();
|
|
381 |
m.line = line;
|
|
382 |
m.pos = int(p - ln);
|
|
383 |
spar++;
|
312 |
384 |
}
|
313 |
|
if(par.GetCount())
|
314 |
|
par.Drop();
|
315 |
|
spar--;
|
316 |
|
}
|
317 |
|
else
|
318 |
|
if(c == ']') {
|
319 |
|
if(brk.GetCount()) {
|
320 |
|
bl--;
|
321 |
|
brk.Drop();
|
|
385 |
else
|
|
386 |
if(c == '[') {
|
|
387 |
bl++;
|
|
388 |
brk.Add(']');
|
|
389 |
Isx& m = par.Add();
|
|
390 |
m.line = line;
|
|
391 |
m.pos = int(p - ln);
|
|
392 |
spar++;
|
322 |
393 |
}
|
323 |
|
if(par.GetCount())
|
324 |
|
par.Drop();
|
325 |
|
spar--;
|
|
394 |
else
|
|
395 |
if(c == ')') {
|
|
396 |
if(brk.GetCount()) {
|
|
397 |
pl--;
|
|
398 |
brk.Drop();
|
|
399 |
}
|
|
400 |
if(par.GetCount())
|
|
401 |
par.Drop();
|
|
402 |
spar--;
|
|
403 |
}
|
|
404 |
else
|
|
405 |
if(c == ']') {
|
|
406 |
if(brk.GetCount()) {
|
|
407 |
bl--;
|
|
408 |
brk.Drop();
|
|
409 |
}
|
|
410 |
if(par.GetCount())
|
|
411 |
par.Drop();
|
|
412 |
spar--;
|
|
413 |
}
|
|
414 |
pc = c;
|
326 |
415 |
}
|
327 |
|
pc = c;
|
328 |
416 |
}
|
|
417 |
if(*p == '/') {
|
|
418 |
linecomment = true;
|
|
419 |
return;
|
|
420 |
}
|
|
421 |
if(*p == '*') {
|
|
422 |
comment = true;
|
|
423 |
p++;
|
|
424 |
}
|
329 |
425 |
}
|
330 |
|
if(*p == '/') {
|
331 |
|
linecomment = true;
|
332 |
|
return;
|
333 |
|
}
|
334 |
|
if(*p == '*') {
|
335 |
|
comment = true;
|
336 |
|
p++;
|
337 |
|
}
|
338 |
426 |
}
|
339 |
427 |
}
|
340 |
428 |
}
|
... | ... | |
353 |
441 |
if(st.macro != SyntaxState::MACRO_CONT)
|
354 |
442 |
st.macro = SyntaxState::MACRO_OFF;
|
355 |
443 |
WString l = GetWLine(st.line);
|
356 |
|
st.ScanSyntax(l, l.End());
|
|
444 |
st.ScanSyntax(l, l.End(), highlight);
|
357 |
445 |
st.line++;
|
358 |
446 |
static int d[] = { 0, 100, 2000 };
|
359 |
447 |
for(int i = 0; i < 3; i++)
|