aboutsummaryrefslogtreecommitdiff
path: root/llex.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-01-25 16:44:21 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-01-25 16:44:21 -0200
commitd83c2a84550221c30a48647fde9c433c65af1802 (patch)
treeea525b29eaabb7cacd54bf7d42ab9e57533e4b5a /llex.c
parentd11e5adf55b11a446671775a6c7803e066fc94e8 (diff)
downloadlua-d83c2a84550221c30a48647fde9c433c65af1802.tar.gz
lua-d83c2a84550221c30a48647fde9c433c65af1802.tar.bz2
lua-d83c2a84550221c30a48647fde9c433c65af1802.zip
performance details.
Diffstat (limited to 'llex.c')
-rw-r--r--llex.c171
1 files changed, 88 insertions, 83 deletions
diff --git a/llex.c b/llex.c
index 49f22860..cd67103e 100644
--- a/llex.c
+++ b/llex.c
@@ -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 */
34static const char *const reserved [] = {"and", "do", "else", "elseif", "end", 34static 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
39void luaX_init (lua_State *L) { 39void 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
60void luaX_error (LexState *ls, const char *s) { 60void 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
234static int read_long_string (lua_State *L, LexState *LS) { 240static 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
276static 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);