diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-01-25 16:44:21 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-01-25 16:44:21 -0200 |
commit | d83c2a84550221c30a48647fde9c433c65af1802 (patch) | |
tree | ea525b29eaabb7cacd54bf7d42ab9e57533e4b5a /llex.c | |
parent | d11e5adf55b11a446671775a6c7803e066fc94e8 (diff) | |
download | lua-d83c2a84550221c30a48647fde9c433c65af1802.tar.gz lua-d83c2a84550221c30a48647fde9c433c65af1802.tar.bz2 lua-d83c2a84550221c30a48647fde9c433c65af1802.zip |
performance details.
Diffstat (limited to 'llex.c')
-rw-r--r-- | llex.c | 171 |
1 files changed, 88 insertions, 83 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.c,v 1.47 1999/12/22 16:58:36 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 1.48 1999/12/30 12:40:29 roberto Exp roberto $ |
3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -33,7 +33,7 @@ | |||
33 | /* ORDER RESERVED */ | 33 | /* ORDER RESERVED */ |
34 | static const char *const reserved [] = {"and", "do", "else", "elseif", "end", | 34 | static const char *const reserved [] = {"and", "do", "else", "elseif", "end", |
35 | "function", "if", "local", "nil", "not", "or", "repeat", "return", "then", | 35 | "function", "if", "local", "nil", "not", "or", "repeat", "return", "then", |
36 | "until", "while"}; | 36 | "until", "while", "", "..", "...", "==", ">=", "<=", "~=", "", "", ""}; |
37 | 37 | ||
38 | 38 | ||
39 | void luaX_init (lua_State *L) { | 39 | void luaX_init (lua_State *L) { |
@@ -57,9 +57,15 @@ void luaX_syntaxerror (LexState *ls, const char *s, const char *token) { | |||
57 | } | 57 | } |
58 | 58 | ||
59 | 59 | ||
60 | void luaX_error (LexState *ls, const char *s) { | 60 | void luaX_error (LexState *ls, const char *s, int token) { |
61 | save(ls->L, '\0'); | 61 | char buff[TOKEN_LEN]; |
62 | luaX_syntaxerror(ls, s, luaL_buffer(ls->L)); | 62 | luaX_token2str(token, buff); |
63 | if (buff[0] == '\0') { | ||
64 | save(ls->L, '\0'); | ||
65 | luaX_syntaxerror(ls, s, luaL_buffer(ls->L)); | ||
66 | } | ||
67 | else | ||
68 | luaX_syntaxerror(ls, s, buff); | ||
63 | } | 69 | } |
64 | 70 | ||
65 | 71 | ||
@@ -156,7 +162,7 @@ static void ifskip (lua_State *L, LexState *LS) { | |||
156 | if (LS->current == '\n') | 162 | if (LS->current == '\n') |
157 | inclinenumber(L, LS); | 163 | inclinenumber(L, LS); |
158 | else if (LS->current == EOZ) | 164 | else if (LS->current == EOZ) |
159 | luaX_error(LS, "input ends inside a $if"); | 165 | luaX_error(LS, "input ends inside a $if", EOS); |
160 | else next(LS); | 166 | else next(LS); |
161 | } | 167 | } |
162 | } | 168 | } |
@@ -231,13 +237,13 @@ static void inclinenumber (lua_State *L, LexState *LS) { | |||
231 | 237 | ||
232 | 238 | ||
233 | 239 | ||
234 | static int read_long_string (lua_State *L, LexState *LS) { | 240 | static void read_long_string (lua_State *L, LexState *LS) { |
235 | int cont = 0; | 241 | int cont = 0; |
236 | for (;;) { | 242 | for (;;) { |
237 | switch (LS->current) { | 243 | switch (LS->current) { |
238 | case EOZ: | 244 | case EOZ: |
239 | luaX_error(LS, "unfinished long string"); | 245 | luaX_error(LS, "unfinished long string", STRING); |
240 | return EOS; /* to avoid warnings */ | 246 | break; /* to avoid warnings */ |
241 | case '[': | 247 | case '[': |
242 | save_and_next(L, LS); | 248 | save_and_next(L, LS); |
243 | if (LS->current == '[') { | 249 | if (LS->current == '[') { |
@@ -264,7 +270,52 @@ static int read_long_string (lua_State *L, LexState *LS) { | |||
264 | save_and_next(L, LS); /* skip the second ']' */ | 270 | save_and_next(L, LS); /* skip the second ']' */ |
265 | LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2), | 271 | LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2), |
266 | L->Mbuffnext-L->Mbuffbase-4); | 272 | L->Mbuffnext-L->Mbuffbase-4); |
267 | return STRING; | 273 | } |
274 | |||
275 | |||
276 | static void read_string (lua_State *L, LexState *LS, int del) { | ||
277 | save_and_next(L, LS); | ||
278 | while (LS->current != del) { | ||
279 | switch (LS->current) { | ||
280 | case EOZ: case '\n': | ||
281 | luaX_error(LS, "unfinished string", STRING); | ||
282 | break; /* to avoid warnings */ | ||
283 | case '\\': | ||
284 | next(LS); /* do not save the '\' */ | ||
285 | switch (LS->current) { | ||
286 | case 'a': save(L, '\a'); next(LS); break; | ||
287 | case 'b': save(L, '\b'); next(LS); break; | ||
288 | case 'f': save(L, '\f'); next(LS); break; | ||
289 | case 'n': save(L, '\n'); next(LS); break; | ||
290 | case 'r': save(L, '\r'); next(LS); break; | ||
291 | case 't': save(L, '\t'); next(LS); break; | ||
292 | case 'v': save(L, '\v'); next(LS); break; | ||
293 | case '\n': save(L, '\n'); inclinenumber(L, LS); break; | ||
294 | case '0': case '1': case '2': case '3': case '4': | ||
295 | case '5': case '6': case '7': case '8': case '9': { | ||
296 | int c = 0; | ||
297 | int i = 0; | ||
298 | do { | ||
299 | c = 10*c + (LS->current-'0'); | ||
300 | next(LS); | ||
301 | } while (++i<3 && isdigit(LS->current)); | ||
302 | if (c != (unsigned char)c) | ||
303 | luaX_error(LS, "escape sequence too large", STRING); | ||
304 | save(L, c); | ||
305 | break; | ||
306 | } | ||
307 | default: /* handles \\, \", \', and \? */ | ||
308 | save(L, LS->current); | ||
309 | next(LS); | ||
310 | } | ||
311 | break; | ||
312 | default: | ||
313 | save_and_next(L, LS); | ||
314 | } | ||
315 | } | ||
316 | save_and_next(L, LS); /* skip delimiter */ | ||
317 | LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1), | ||
318 | L->Mbuffnext-L->Mbuffbase-2); | ||
268 | } | 319 | } |
269 | 320 | ||
270 | 321 | ||
@@ -283,10 +334,9 @@ int luaX_lex (LexState *LS) { | |||
283 | continue; | 334 | continue; |
284 | 335 | ||
285 | case '-': | 336 | case '-': |
286 | save_and_next(L, LS); | 337 | next(LS); |
287 | if (LS->current != '-') return '-'; | 338 | if (LS->current != '-') return '-'; |
288 | do { next(LS); } while (LS->current != '\n' && LS->current != EOZ); | 339 | do { next(LS); } while (LS->current != '\n' && LS->current != EOZ); |
289 | luaL_resetbuffer(L); | ||
290 | continue; | 340 | continue; |
291 | 341 | ||
292 | case '[': | 342 | case '[': |
@@ -294,88 +344,41 @@ int luaX_lex (LexState *LS) { | |||
294 | if (LS->current != '[') return '['; | 344 | if (LS->current != '[') return '['; |
295 | else { | 345 | else { |
296 | save_and_next(L, LS); /* pass the second '[' */ | 346 | save_and_next(L, LS); /* pass the second '[' */ |
297 | return read_long_string(L, LS); | 347 | read_long_string(L, LS); |
348 | return STRING; | ||
298 | } | 349 | } |
299 | 350 | ||
300 | case '=': | 351 | case '=': |
301 | save_and_next(L, LS); | 352 | next(LS); |
302 | if (LS->current != '=') return '='; | 353 | if (LS->current != '=') return '='; |
303 | else { save_and_next(L, LS); return EQ; } | 354 | else { next(LS); return EQ; } |
304 | 355 | ||
305 | case '<': | 356 | case '<': |
306 | save_and_next(L, LS); | 357 | next(LS); |
307 | if (LS->current != '=') return '<'; | 358 | if (LS->current != '=') return '<'; |
308 | else { save_and_next(L, LS); return LE; } | 359 | else { next(LS); return LE; } |
309 | 360 | ||
310 | case '>': | 361 | case '>': |
311 | save_and_next(L, LS); | 362 | next(LS); |
312 | if (LS->current != '=') return '>'; | 363 | if (LS->current != '=') return '>'; |
313 | else { save_and_next(L, LS); return GE; } | 364 | else { next(LS); return GE; } |
314 | 365 | ||
315 | case '~': | 366 | case '~': |
316 | save_and_next(L, LS); | 367 | next(LS); |
317 | if (LS->current != '=') return '~'; | 368 | if (LS->current != '=') return '~'; |
318 | else { save_and_next(L, LS); return NE; } | 369 | else { next(LS); return NE; } |
319 | 370 | ||
320 | case '"': | 371 | case '"': |
321 | case '\'': { | 372 | case '\'': |
322 | int del = LS->current; | 373 | read_string(L, LS, LS->current); |
323 | save_and_next(L, LS); | ||
324 | while (LS->current != del) { | ||
325 | switch (LS->current) { | ||
326 | case EOZ: | ||
327 | case '\n': | ||
328 | luaX_error(LS, "unfinished string"); | ||
329 | return EOS; /* to avoid warnings */ | ||
330 | case '\\': | ||
331 | next(LS); /* do not save the '\' */ | ||
332 | switch (LS->current) { | ||
333 | case 'a': save(L, '\a'); next(LS); break; | ||
334 | case 'b': save(L, '\b'); next(LS); break; | ||
335 | case 'f': save(L, '\f'); next(LS); break; | ||
336 | case 'n': save(L, '\n'); next(LS); break; | ||
337 | case 'r': save(L, '\r'); next(LS); break; | ||
338 | case 't': save(L, '\t'); next(LS); break; | ||
339 | case 'v': save(L, '\v'); next(LS); break; | ||
340 | case '\n': save(L, '\n'); inclinenumber(L, LS); break; | ||
341 | default : { | ||
342 | if (isdigit(LS->current)) { | ||
343 | int c = 0; | ||
344 | int i = 0; | ||
345 | do { | ||
346 | c = 10*c + (LS->current-'0'); | ||
347 | next(LS); | ||
348 | } while (++i<3 && isdigit(LS->current)); | ||
349 | if (c != (unsigned char)c) | ||
350 | luaX_error(LS, "escape sequence too large"); | ||
351 | save(L, c); | ||
352 | } | ||
353 | else { /* handles \, ", ', and ? */ | ||
354 | save(L, LS->current); | ||
355 | next(LS); | ||
356 | } | ||
357 | break; | ||
358 | } | ||
359 | } | ||
360 | break; | ||
361 | default: | ||
362 | save_and_next(L, LS); | ||
363 | } | ||
364 | } | ||
365 | save_and_next(L, LS); /* skip delimiter */ | ||
366 | LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1), | ||
367 | L->Mbuffnext-L->Mbuffbase-2); | ||
368 | return STRING; | 374 | return STRING; |
369 | } | ||
370 | 375 | ||
371 | case '.': | 376 | case '.': |
372 | save_and_next(L, LS); | 377 | save_and_next(L, LS); |
373 | if (LS->current == '.') | 378 | if (LS->current == '.') { |
374 | { | 379 | next(LS); |
375 | save_and_next(L, LS); | 380 | if (LS->current == '.') { |
376 | if (LS->current == '.') | 381 | next(LS); |
377 | { | ||
378 | save_and_next(L, LS); | ||
379 | return DOTS; /* ... */ | 382 | return DOTS; /* ... */ |
380 | } | 383 | } |
381 | else return CONC; /* .. */ | 384 | else return CONC; /* .. */ |
@@ -392,14 +395,14 @@ int luaX_lex (LexState *LS) { | |||
392 | save_and_next(L, LS); | 395 | save_and_next(L, LS); |
393 | if (LS->current == '.') { | 396 | if (LS->current == '.') { |
394 | save(L, '.'); | 397 | save(L, '.'); |
395 | luaX_error(LS, | 398 | luaX_error(LS, "ambiguous syntax" |
396 | "ambiguous syntax (decimal point x string concatenation)"); | 399 | " (decimal point x string concatenation)", NUMBER); |
397 | } | 400 | } |
398 | } | 401 | } |
399 | fraction: /* LUA_NUMBER */ | 402 | fraction: /* LUA_NUMBER */ |
400 | while (isdigit(LS->current)) | 403 | while (isdigit(LS->current)) |
401 | save_and_next(L, LS); | 404 | save_and_next(L, LS); |
402 | if (toupper(LS->current) == 'E') { | 405 | if (LS->current == 'e' || LS->current == 'E') { |
403 | save_and_next(L, LS); /* read 'E' */ | 406 | save_and_next(L, LS); /* read 'E' */ |
404 | if (LS->current == '+' || LS->current == '-') | 407 | if (LS->current == '+' || LS->current == '-') |
405 | save_and_next(L, LS); /* optional exponent sign */ | 408 | save_and_next(L, LS); /* optional exponent sign */ |
@@ -408,23 +411,25 @@ int luaX_lex (LexState *LS) { | |||
408 | } | 411 | } |
409 | save(L, '\0'); | 412 | save(L, '\0'); |
410 | if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->seminfo.r)) | 413 | if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->seminfo.r)) |
411 | luaX_error(LS, "malformed number"); | 414 | luaX_error(LS, "malformed number", NUMBER); |
412 | return NUMBER; | 415 | return NUMBER; |
413 | 416 | ||
414 | case EOZ: | 417 | case EOZ: |
415 | if (LS->iflevel > 0) | 418 | if (LS->iflevel > 0) |
416 | luaX_error(LS, "input ends inside a $if"); | 419 | luaX_error(LS, "input ends inside a $if", EOS); |
417 | return EOS; | 420 | return EOS; |
418 | 421 | ||
422 | case '_': goto tname; | ||
423 | |||
419 | default: | 424 | default: |
420 | if (LS->current != '_' && !isalpha(LS->current)) { | 425 | if (!isalpha(LS->current)) { |
421 | int c = LS->current; | 426 | int c = LS->current; |
422 | if (iscntrl(c)) | 427 | if (iscntrl(c)) |
423 | luaX_invalidchar(LS, c); | 428 | luaX_invalidchar(LS, c); |
424 | save_and_next(L, LS); | 429 | next(LS); |
425 | return c; | 430 | return c; |
426 | } | 431 | } |
427 | else { /* identifier or reserved word */ | 432 | tname: { /* identifier or reserved word */ |
428 | TaggedString *ts; | 433 | TaggedString *ts; |
429 | do { | 434 | do { |
430 | save_and_next(L, LS); | 435 | save_and_next(L, LS); |