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); |
