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 | |
| parent | d11e5adf55b11a446671775a6c7803e066fc94e8 (diff) | |
| download | lua-d83c2a84550221c30a48647fde9c433c65af1802.tar.gz lua-d83c2a84550221c30a48647fde9c433c65af1802.tar.bz2 lua-d83c2a84550221c30a48647fde9c433c65af1802.zip | |
performance details.
| -rw-r--r-- | llex.c | 171 | ||||
| -rw-r--r-- | llex.h | 4 | ||||
| -rw-r--r-- | lobject.c | 17 | ||||
| -rw-r--r-- | lparser.c | 87 |
4 files changed, 146 insertions, 133 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); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.h,v 1.15 1999/11/22 13:12:07 roberto Exp roberto $ | 2 | ** $Id: llex.h,v 1.16 1999/12/27 17:33:22 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 | */ |
| @@ -63,7 +63,7 @@ void luaX_init (lua_State *L); | |||
| 63 | void luaX_setinput (lua_State *L, LexState *LS, ZIO *z); | 63 | void luaX_setinput (lua_State *L, LexState *LS, ZIO *z); |
| 64 | int luaX_lex (LexState *LS); | 64 | int luaX_lex (LexState *LS); |
| 65 | void luaX_syntaxerror (LexState *ls, const char *s, const char *token); | 65 | void luaX_syntaxerror (LexState *ls, const char *s, const char *token); |
| 66 | void luaX_error (LexState *ls, const char *s); | 66 | void luaX_error (LexState *ls, const char *s, int token); |
| 67 | void luaX_token2str (int token, char *s); | 67 | void luaX_token2str (int token, char *s); |
| 68 | 68 | ||
| 69 | 69 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 1.28 1999/12/23 18:19:57 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 1.29 1999/12/30 18:28:40 roberto Exp roberto $ |
| 3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -87,9 +87,9 @@ int luaO_str2d (const char *s, real *result) { /* LUA_NUMBER */ | |||
| 87 | int point = 0; /* number of decimal digits */ | 87 | int point = 0; /* number of decimal digits */ |
| 88 | int sig; | 88 | int sig; |
| 89 | while (isspace((unsigned char)*s)) s++; | 89 | while (isspace((unsigned char)*s)) s++; |
| 90 | sig = 1; | 90 | sig = 0; |
| 91 | switch (*s) { | 91 | switch (*s) { |
| 92 | case '-': sig = -1; /* go through */ | 92 | case '-': sig = 1; /* go through */ |
| 93 | case '+': s++; | 93 | case '+': s++; |
| 94 | } | 94 | } |
| 95 | if (! (isdigit((unsigned char)*s) || | 95 | if (! (isdigit((unsigned char)*s) || |
| @@ -104,20 +104,21 @@ int luaO_str2d (const char *s, real *result) { /* LUA_NUMBER */ | |||
| 104 | point++; | 104 | point++; |
| 105 | } | 105 | } |
| 106 | } | 106 | } |
| 107 | a *= sig; | 107 | if (sig) a = -a; |
| 108 | if (toupper((unsigned char)*s) == 'E') { | 108 | if (*s == 'e' || *s == 'E') { |
| 109 | int e = 0; | 109 | int e = 0; |
| 110 | s++; | 110 | s++; |
| 111 | sig = 1; | 111 | sig = 0; |
| 112 | switch (*s) { | 112 | switch (*s) { |
| 113 | case '-': sig = -1; /* go through */ | 113 | case '-': sig = 1; /* go through */ |
| 114 | case '+': s++; | 114 | case '+': s++; |
| 115 | } | 115 | } |
| 116 | if (!isdigit((unsigned char)*s)) return 0; /* no digit in the exponent? */ | 116 | if (!isdigit((unsigned char)*s)) return 0; /* no digit in the exponent? */ |
| 117 | do { | 117 | do { |
| 118 | e = 10*e + (*(s++)-'0'); | 118 | e = 10*e + (*(s++)-'0'); |
| 119 | } while (isdigit((unsigned char)*s)); | 119 | } while (isdigit((unsigned char)*s)); |
| 120 | point -= sig*e; | 120 | if (sig) e = -e; |
| 121 | point -= e; | ||
| 121 | } | 122 | } |
| 122 | while (isspace((unsigned char)*s)) s++; | 123 | while (isspace((unsigned char)*s)) s++; |
| 123 | if (*s != '\0') return 0; /* invalid trailing characters? */ | 124 | if (*s != '\0') return 0; /* invalid trailing characters? */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.54 2000/01/12 16:24:39 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.55 2000/01/25 13:57:18 roberto Exp roberto $ |
| 3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -119,11 +119,16 @@ static void exp1 (LexState *ls); | |||
| 119 | 119 | ||
| 120 | 120 | ||
| 121 | 121 | ||
| 122 | static void luaY_error (LexState *ls, const char *msg) { | ||
| 123 | luaX_error(ls, msg, ls->token); | ||
| 124 | } | ||
| 125 | |||
| 126 | |||
| 122 | static void checklimit (LexState *ls, int val, int limit, const char *msg) { | 127 | static void checklimit (LexState *ls, int val, int limit, const char *msg) { |
| 123 | if (val > limit) { | 128 | if (val > limit) { |
| 124 | char buff[100]; | 129 | char buff[100]; |
| 125 | sprintf(buff, "too many %.50s (limit=%d)", msg, limit); | 130 | sprintf(buff, "too many %.50s (limit=%d)", msg, limit); |
| 126 | luaX_error(ls, buff); | 131 | luaY_error(ls, buff); |
| 127 | } | 132 | } |
| 128 | } | 133 | } |
| 129 | 134 | ||
| @@ -145,7 +150,7 @@ static void deltastack (LexState *ls, int delta) { | |||
| 145 | fs->stacksize += delta; | 150 | fs->stacksize += delta; |
| 146 | if (fs->stacksize > fs->maxstacksize) { | 151 | if (fs->stacksize > fs->maxstacksize) { |
| 147 | if (fs->stacksize > MAX_BYTE) | 152 | if (fs->stacksize > MAX_BYTE) |
| 148 | luaX_error(ls, "function/expression too complex"); | 153 | luaY_error(ls, "function/expression too complex"); |
| 149 | fs->maxstacksize = fs->stacksize; | 154 | fs->maxstacksize = fs->stacksize; |
| 150 | } | 155 | } |
| 151 | } | 156 | } |
| @@ -160,7 +165,7 @@ static void code_oparg_at (LexState *ls, int pc, OpCode op, | |||
| 160 | code[pc+1] = (Byte)arg; | 165 | code[pc+1] = (Byte)arg; |
| 161 | } | 166 | } |
| 162 | else if (arg > MAX_ARG) | 167 | else if (arg > MAX_ARG) |
| 163 | luaX_error(ls, "code too long"); | 168 | luaY_error(ls, "code too long"); |
| 164 | else { /* MAX_BYTE < arg < MAX_ARG */ | 169 | else { /* MAX_BYTE < arg < MAX_ARG */ |
| 165 | if (arg > MAX_WORD) { | 170 | if (arg > MAX_WORD) { |
| 166 | code[pc] = (Byte)LONGARG; | 171 | code[pc] = (Byte)LONGARG; |
| @@ -599,20 +604,6 @@ static void close_func (LexState *ls) { | |||
| 599 | } | 604 | } |
| 600 | 605 | ||
| 601 | 606 | ||
| 602 | |||
| 603 | static const int expfollow [] = {ELSE, ELSEIF, THEN, IF, WHILE, REPEAT, | ||
| 604 | DO, NAME, LOCAL, FUNCTION, END, UNTIL, RETURN, ')', ']', '}', ';', | ||
| 605 | EOS, ',', 0}; | ||
| 606 | |||
| 607 | |||
| 608 | static int is_in (int tok, const int *toks) { | ||
| 609 | const int *t; | ||
| 610 | for (t=toks; *t; t++) | ||
| 611 | if (*t == tok) return t-toks; | ||
| 612 | return -1; | ||
| 613 | } | ||
| 614 | |||
| 615 | |||
| 616 | static void next (LexState *ls) { | 607 | static void next (LexState *ls) { |
| 617 | ls->token = luaX_lex(ls); | 608 | ls->token = luaX_lex(ls); |
| 618 | } | 609 | } |
| @@ -622,12 +613,12 @@ static void error_expected (LexState *ls, int token) { | |||
| 622 | char buff[100], t[TOKEN_LEN]; | 613 | char buff[100], t[TOKEN_LEN]; |
| 623 | luaX_token2str(token, t); | 614 | luaX_token2str(token, t); |
| 624 | sprintf(buff, "`%.20s' expected", t); | 615 | sprintf(buff, "`%.20s' expected", t); |
| 625 | luaX_error(ls, buff); | 616 | luaY_error(ls, buff); |
| 626 | } | 617 | } |
| 627 | 618 | ||
| 628 | 619 | ||
| 629 | static void error_unexpected (LexState *ls) { | 620 | static void error_unexpected (LexState *ls) { |
| 630 | luaX_error(ls, "unexpected token"); | 621 | luaY_error(ls, "unexpected token"); |
| 631 | } | 622 | } |
| 632 | 623 | ||
| 633 | 624 | ||
| @@ -641,7 +632,7 @@ static void error_unmatched (LexState *ls, int what, int who, int where) { | |||
| 641 | luaX_token2str(who, t_who); | 632 | luaX_token2str(who, t_who); |
| 642 | sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)", | 633 | sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)", |
| 643 | t_what, t_who, where); | 634 | t_what, t_who, where); |
| 644 | luaX_error(ls, buff); | 635 | luaY_error(ls, buff); |
| 645 | } | 636 | } |
| 646 | } | 637 | } |
| 647 | 638 | ||
| @@ -661,7 +652,7 @@ static void check_match (LexState *ls, int what, int who, int where) { | |||
| 661 | static int checkname (LexState *ls) { | 652 | static int checkname (LexState *ls) { |
| 662 | int sc; | 653 | int sc; |
| 663 | if (ls->token != NAME) | 654 | if (ls->token != NAME) |
| 664 | luaX_error(ls, "<name> expected"); | 655 | luaY_error(ls, "<name> expected"); |
| 665 | sc = string_constant(ls, ls->fs, ls->seminfo.ts); | 656 | sc = string_constant(ls, ls->fs, ls->seminfo.ts); |
| 666 | next(ls); | 657 | next(ls); |
| 667 | return sc; | 658 | return sc; |
| @@ -691,7 +682,7 @@ TProtoFunc *luaY_parser (lua_State *L, ZIO *z) { | |||
| 691 | next(&lexstate); /* read first token */ | 682 | next(&lexstate); /* read first token */ |
| 692 | chunk(&lexstate); | 683 | chunk(&lexstate); |
| 693 | if (lexstate.token != EOS) | 684 | if (lexstate.token != EOS) |
| 694 | luaX_error(&lexstate, "<eof> expected"); | 685 | luaY_error(&lexstate, "<eof> expected"); |
| 695 | close_func(&lexstate); | 686 | close_func(&lexstate); |
| 696 | return funcstate.f; | 687 | return funcstate.f; |
| 697 | } | 688 | } |
| @@ -782,7 +773,7 @@ static int funcparams (LexState *ls, int slf, vardesc *v) { | |||
| 782 | break; | 773 | break; |
| 783 | 774 | ||
| 784 | default: | 775 | default: |
| 785 | luaX_error(ls, "function arguments expected"); | 776 | luaY_error(ls, "function arguments expected"); |
| 786 | break; | 777 | break; |
| 787 | } | 778 | } |
| 788 | code_setname(ls, v); | 779 | code_setname(ls, v); |
| @@ -871,7 +862,7 @@ static void recfield (LexState *ls) { | |||
| 871 | check(ls, ']'); | 862 | check(ls, ']'); |
| 872 | break; | 863 | break; |
| 873 | 864 | ||
| 874 | default: luaX_error(ls, "<name> or `[' expected"); | 865 | default: luaY_error(ls, "<name> or `[' expected"); |
| 875 | } | 866 | } |
| 876 | check(ls, '='); | 867 | check(ls, '='); |
| 877 | exp1(ls); | 868 | exp1(ls); |
| @@ -977,7 +968,7 @@ static void constructor (LexState *ls) { | |||
| 977 | next(ls); | 968 | next(ls); |
| 978 | constructor_part(ls, &other_cd); | 969 | constructor_part(ls, &other_cd); |
| 979 | if (cd.k == other_cd.k) /* repeated parts? */ | 970 | if (cd.k == other_cd.k) /* repeated parts? */ |
| 980 | luaX_error(ls, "invalid constructor syntax"); | 971 | luaY_error(ls, "invalid constructor syntax"); |
| 981 | nelems += other_cd.n; | 972 | nelems += other_cd.n; |
| 982 | } | 973 | } |
| 983 | check_match(ls, '}', '{', line); | 974 | check_match(ls, '}', '{', line); |
| @@ -992,8 +983,8 @@ static void constructor (LexState *ls) { | |||
| 992 | /* | 983 | /* |
| 993 | ** {====================================================================== | 984 | ** {====================================================================== |
| 994 | ** For parsing expressions, we use a classic stack with priorities. | 985 | ** For parsing expressions, we use a classic stack with priorities. |
| 995 | ** Each binary operator is represented by its index in `binop' + FIRSTBIN | 986 | ** Each binary operator is represented by an index: EQ=2, NE=3, ... '^'=13. |
| 996 | ** (EQ=2, NE=3, ... '^'=13). The unary NOT is 0 and UNMINUS is 1. | 987 | ** The unary NOT is 0 and UNMINUS is 1. |
| 997 | ** ======================================================================= | 988 | ** ======================================================================= |
| 998 | */ | 989 | */ |
| 999 | 990 | ||
| @@ -1008,8 +999,6 @@ static void constructor (LexState *ls) { | |||
| 1008 | */ | 999 | */ |
| 1009 | #define POW 13 | 1000 | #define POW 13 |
| 1010 | 1001 | ||
| 1011 | static const int binop [] = {EQ, NE, '>', '<', LE, GE, CONC, | ||
| 1012 | '+', '-', '*', '/', '^', 0}; | ||
| 1013 | 1002 | ||
| 1014 | static const int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6}; | 1003 | static const int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6}; |
| 1015 | 1004 | ||
| @@ -1024,10 +1013,31 @@ typedef struct stack_op { | |||
| 1024 | } stack_op; | 1013 | } stack_op; |
| 1025 | 1014 | ||
| 1026 | 1015 | ||
| 1016 | /* | ||
| 1017 | ** returns the index of a binary operator | ||
| 1018 | */ | ||
| 1019 | static int binop (int op) { | ||
| 1020 | switch (op) { | ||
| 1021 | case EQ: return FIRSTBIN; | ||
| 1022 | case NE: return FIRSTBIN+1; | ||
| 1023 | case '>': return FIRSTBIN+2; | ||
| 1024 | case '<': return FIRSTBIN+3; | ||
| 1025 | case LE: return FIRSTBIN+4; | ||
| 1026 | case GE: return FIRSTBIN+5; | ||
| 1027 | case CONC: return FIRSTBIN+6; | ||
| 1028 | case '+': return FIRSTBIN+7; | ||
| 1029 | case '-': return FIRSTBIN+8; | ||
| 1030 | case '*': return FIRSTBIN+9; | ||
| 1031 | case '/': return FIRSTBIN+10; | ||
| 1032 | case '^': return FIRSTBIN+11; | ||
| 1033 | default: return -1; | ||
| 1034 | } | ||
| 1035 | } | ||
| 1036 | |||
| 1027 | 1037 | ||
| 1028 | static void push (LexState *ls, stack_op *s, int op) { | 1038 | static void push (LexState *ls, stack_op *s, int op) { |
| 1029 | if (s->top >= MAXOPS) | 1039 | if (s->top >= MAXOPS) |
| 1030 | luaX_error(ls, "expression too complex"); | 1040 | luaY_error(ls, "expression too complex"); |
| 1031 | s->ops[s->top++] = op; | 1041 | s->ops[s->top++] = op; |
| 1032 | } | 1042 | } |
| 1033 | 1043 | ||
| @@ -1086,7 +1096,7 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) { | |||
| 1086 | return; | 1096 | return; |
| 1087 | 1097 | ||
| 1088 | default: | 1098 | default: |
| 1089 | luaX_error(ls, "<expression> expected"); | 1099 | luaY_error(ls, "<expression> expected"); |
| 1090 | return; | 1100 | return; |
| 1091 | } | 1101 | } |
| 1092 | v->k = VEXP; v->info = 0; | 1102 | v->k = VEXP; v->info = 0; |
| @@ -1108,8 +1118,7 @@ static void arith_exp (LexState *ls, vardesc *v) { | |||
| 1108 | int op; | 1118 | int op; |
| 1109 | s.top = 0; | 1119 | s.top = 0; |
| 1110 | prefixexp(ls, v, &s); | 1120 | prefixexp(ls, v, &s); |
| 1111 | while ((op = is_in(ls->token, binop)) >= 0) { | 1121 | while ((op = binop(ls->token)) >= 0) { |
| 1112 | op += FIRSTBIN; | ||
| 1113 | lua_pushvar(ls, v); | 1122 | lua_pushvar(ls, v); |
| 1114 | /* '^' is right associative, so must 'simulate' a higher priority */ | 1123 | /* '^' is right associative, so must 'simulate' a higher priority */ |
| 1115 | pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]); | 1124 | pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]); |
| @@ -1129,8 +1138,6 @@ static void exp1 (LexState *ls) { | |||
| 1129 | vardesc v; | 1138 | vardesc v; |
| 1130 | expr(ls, &v); | 1139 | expr(ls, &v); |
| 1131 | lua_pushvar(ls, &v); | 1140 | lua_pushvar(ls, &v); |
| 1132 | if (is_in(ls->token, expfollow) < 0) | ||
| 1133 | luaX_error(ls, "malformed expression"); | ||
| 1134 | } | 1141 | } |
| 1135 | 1142 | ||
| 1136 | 1143 | ||
| @@ -1180,7 +1187,7 @@ static int assignment (LexState *ls, vardesc *v, int nvars) { | |||
| 1180 | next(ls); | 1187 | next(ls); |
| 1181 | var_or_func(ls, &nv); | 1188 | var_or_func(ls, &nv); |
| 1182 | if (nv.k == VEXP) | 1189 | if (nv.k == VEXP) |
| 1183 | luaX_error(ls, "syntax error"); | 1190 | luaY_error(ls, "syntax error"); |
| 1184 | left = assignment(ls, &nv, nvars+1); | 1191 | left = assignment(ls, &nv, nvars+1); |
| 1185 | } | 1192 | } |
| 1186 | else { /* assignment -> '=' explist1 */ | 1193 | else { /* assignment -> '=' explist1 */ |
| @@ -1313,7 +1320,7 @@ static void namestat (LexState *ls) { | |||
| 1313 | var_or_func(ls, &v); | 1320 | var_or_func(ls, &v); |
| 1314 | if (v.k == VEXP) { /* stat -> func */ | 1321 | if (v.k == VEXP) { /* stat -> func */ |
| 1315 | if (v.info == 0) /* is just an upper value? */ | 1322 | if (v.info == 0) /* is just an upper value? */ |
| 1316 | luaX_error(ls, "syntax error"); | 1323 | luaY_error(ls, "syntax error"); |
| 1317 | close_exp(ls, v.info, 0); | 1324 | close_exp(ls, v.info, 0); |
| 1318 | } | 1325 | } |
| 1319 | else { /* stat -> ['%'] NAME assignment */ | 1326 | else { /* stat -> ['%'] NAME assignment */ |
| @@ -1410,14 +1417,14 @@ static void parlist (LexState *ls) { | |||
| 1410 | case NAME: /* tailparlist -> NAME [',' tailparlist] */ | 1417 | case NAME: /* tailparlist -> NAME [',' tailparlist] */ |
| 1411 | goto init; | 1418 | goto init; |
| 1412 | 1419 | ||
| 1413 | default: luaX_error(ls, "<name> or `...' expected"); | 1420 | default: luaY_error(ls, "<name> or `...' expected"); |
| 1414 | } | 1421 | } |
| 1415 | } | 1422 | } |
| 1416 | break; | 1423 | break; |
| 1417 | 1424 | ||
| 1418 | case ')': break; /* parlist -> empty */ | 1425 | case ')': break; /* parlist -> empty */ |
| 1419 | 1426 | ||
| 1420 | default: luaX_error(ls, "<name> or `...' expected"); | 1427 | default: luaY_error(ls, "<name> or `...' expected"); |
| 1421 | } | 1428 | } |
| 1422 | code_args(ls, nparams, dots); | 1429 | code_args(ls, nparams, dots); |
| 1423 | } | 1430 | } |
