diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-05-24 15:04:17 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-05-24 15:04:17 -0300 |
commit | 677313da32d58b418c15dc5f4a6ff435fb63d365 (patch) | |
tree | 418e702f7479e051be69b41fd133b13d846834d2 | |
parent | ef62b340e0a6b7b18931000dcbb19c4703bfe0e8 (diff) | |
download | lua-677313da32d58b418c15dc5f4a6ff435fb63d365.tar.gz lua-677313da32d58b418c15dc5f4a6ff435fb63d365.tar.bz2 lua-677313da32d58b418c15dc5f4a6ff435fb63d365.zip |
bug: record-constructor starting with an upvalue name gets an error
-rw-r--r-- | bugs | 8 | ||||
-rw-r--r-- | lcode.c | 4 | ||||
-rw-r--r-- | llex.c | 13 | ||||
-rw-r--r-- | llex.h | 17 | ||||
-rw-r--r-- | lparser.c | 315 |
5 files changed, 183 insertions, 174 deletions
@@ -179,4 +179,12 @@ Tue May 2 15:27:58 EST 2000 | |||
179 | ** lparser.c | 179 | ** lparser.c |
180 | Fri May 12 15:11:12 EST 2000 | 180 | Fri May 12 15:11:12 EST 2000 |
181 | >> first element in a list constructor is not adjusted to one value | 181 | >> first element in a list constructor is not adjusted to one value |
182 | >> (e.g. «a = {gsub('a','a','')}») | ||
182 | (by Tomas; since 4.0a) | 183 | (by Tomas; since 4.0a) |
184 | |||
185 | ** lparser.c | ||
186 | Wed May 24 14:50:16 EST 2000 | ||
187 | >> record-constructor starting with an upvalue name gets an error | ||
188 | >> (e.g. «local a; function f() x = {a=1} end») | ||
189 | (by Edgar Toernig; since 3.1) | ||
190 | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 1.31 2000/05/22 18:44:46 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.32 2000/05/24 13:54:49 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | 20 | ||
21 | void luaK_error (LexState *ls, const char *msg) { | 21 | void luaK_error (LexState *ls, const char *msg) { |
22 | luaX_error(ls, msg, ls->token); | 22 | luaX_error(ls, msg, ls->t.token); |
23 | } | 23 | } |
24 | 24 | ||
25 | 25 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.c,v 1.58 2000/05/08 19:32:53 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 1.59 2000/05/24 13:54:49 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 | */ |
@@ -54,7 +54,7 @@ void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) { | |||
54 | if (val > limit) { | 54 | if (val > limit) { |
55 | char buff[100]; | 55 | char buff[100]; |
56 | sprintf(buff, "too many %.50s (limit=%d)", msg, limit); | 56 | sprintf(buff, "too many %.50s (limit=%d)", msg, limit); |
57 | luaX_error(ls, buff, ls->token); | 57 | luaX_error(ls, buff, ls->t.token); |
58 | } | 58 | } |
59 | } | 59 | } |
60 | 60 | ||
@@ -108,6 +108,7 @@ static void firstline (LexState *LS) | |||
108 | void luaX_setinput (lua_State *L, LexState *LS, ZIO *z) { | 108 | void luaX_setinput (lua_State *L, LexState *LS, ZIO *z) { |
109 | LS->L = L; | 109 | LS->L = L; |
110 | LS->current = '\n'; | 110 | LS->current = '\n'; |
111 | LS->next.token = TK_EOS; /* no next token */ | ||
111 | LS->linenumber = 0; | 112 | LS->linenumber = 0; |
112 | LS->iflevel = 0; | 113 | LS->iflevel = 0; |
113 | LS->ifstate[0].skip = 0; | 114 | LS->ifstate[0].skip = 0; |
@@ -281,7 +282,7 @@ static void read_long_string (lua_State *L, LexState *LS) { | |||
281 | } | 282 | } |
282 | } endloop: | 283 | } endloop: |
283 | save_and_next(L, LS); /* skip the second ']' */ | 284 | save_and_next(L, LS); /* skip the second ']' */ |
284 | LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2), | 285 | LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+2), |
285 | L->Mbuffnext-L->Mbuffbase-4); | 286 | L->Mbuffnext-L->Mbuffbase-4); |
286 | } | 287 | } |
287 | 288 | ||
@@ -327,7 +328,7 @@ static void read_string (lua_State *L, LexState *LS, int del) { | |||
327 | } | 328 | } |
328 | } | 329 | } |
329 | save_and_next(L, LS); /* skip delimiter */ | 330 | save_and_next(L, LS); /* skip delimiter */ |
330 | LS->seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1), | 331 | LS->t.seminfo.ts = luaS_newlstr(L, L->Mbuffer+(L->Mbuffbase+1), |
331 | L->Mbuffnext-L->Mbuffbase-2); | 332 | L->Mbuffnext-L->Mbuffbase-2); |
332 | } | 333 | } |
333 | 334 | ||
@@ -426,7 +427,7 @@ int luaX_lex (LexState *LS) { | |||
426 | save_and_next(L, LS); | 427 | save_and_next(L, LS); |
427 | } | 428 | } |
428 | save(L, '\0'); | 429 | save(L, '\0'); |
429 | if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->seminfo.r)) | 430 | if (!luaO_str2d(L->Mbuffer+L->Mbuffbase, &LS->t.seminfo.r)) |
430 | luaX_error(LS, "malformed number", TK_NUMBER); | 431 | luaX_error(LS, "malformed number", TK_NUMBER); |
431 | return TK_NUMBER; | 432 | return TK_NUMBER; |
432 | 433 | ||
@@ -455,7 +456,7 @@ int luaX_lex (LexState *LS) { | |||
455 | ts = luaS_new(L, L->Mbuffer+L->Mbuffbase); | 456 | ts = luaS_new(L, L->Mbuffer+L->Mbuffbase); |
456 | if (ts->marked >= RESERVEDMARK) /* reserved word? */ | 457 | if (ts->marked >= RESERVEDMARK) /* reserved word? */ |
457 | return ts->marked-RESERVEDMARK+FIRST_RESERVED; | 458 | return ts->marked-RESERVEDMARK+FIRST_RESERVED; |
458 | LS->seminfo.ts = ts; | 459 | LS->t.seminfo.ts = ts; |
459 | return TK_NAME; | 460 | return TK_NAME; |
460 | } | 461 | } |
461 | } | 462 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.h,v 1.24 2000/04/12 18:57:19 roberto Exp roberto $ | 2 | ** $Id: llex.h,v 1.25 2000/05/24 13:54:49 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 | */ |
@@ -44,15 +44,20 @@ struct ifState { | |||
44 | }; | 44 | }; |
45 | 45 | ||
46 | 46 | ||
47 | typedef struct LexState { | 47 | typedef struct Token { |
48 | int current; /* look ahead character */ | 48 | int token; |
49 | int token; /* look ahead token */ | ||
50 | struct FuncState *fs; /* `FuncState' is private to the parser */ | ||
51 | struct lua_State *L; | ||
52 | union { | 49 | union { |
53 | Number r; | 50 | Number r; |
54 | TString *ts; | 51 | TString *ts; |
55 | } seminfo; /* semantics information */ | 52 | } seminfo; /* semantics information */ |
53 | } Token; | ||
54 | |||
55 | typedef struct LexState { | ||
56 | int current; /* look ahead character */ | ||
57 | Token t; /* look ahead token */ | ||
58 | Token next; /* to `unget' a token */ | ||
59 | struct FuncState *fs; /* `FuncState' is private to the parser */ | ||
60 | struct lua_State *L; | ||
56 | struct zio *z; /* input stream */ | 61 | struct zio *z; /* input stream */ |
57 | int linenumber; /* input line counter */ | 62 | int linenumber; /* input line counter */ |
58 | int iflevel; /* level of nested $if's (for lexical analysis) */ | 63 | int iflevel; /* level of nested $if's (for lexical analysis) */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.88 2000/05/22 18:44:46 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.89 2000/05/24 13:54:49 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 | */ |
@@ -54,8 +54,20 @@ static void expr (LexState *ls, expdesc *v); | |||
54 | static void exp1 (LexState *ls); | 54 | static void exp1 (LexState *ls); |
55 | 55 | ||
56 | 56 | ||
57 | |||
57 | static void next (LexState *ls) { | 58 | static void next (LexState *ls) { |
58 | ls->token = luaX_lex(ls); | 59 | if (ls->next.token != TK_EOS) { /* is there an `unget' token? */ |
60 | ls->t = ls->next; /* use this one */ | ||
61 | ls->next.token = TK_EOS; /* and discharge it */ | ||
62 | } | ||
63 | else | ||
64 | ls->t.token = luaX_lex(ls); /* read next token */ | ||
65 | } | ||
66 | |||
67 | |||
68 | static void ungettoken (LexState *ls, Token *t) { | ||
69 | ls->next = ls->t; | ||
70 | ls->t = *t; | ||
59 | } | 71 | } |
60 | 72 | ||
61 | 73 | ||
@@ -73,7 +85,7 @@ static void error_unexpected (LexState *ls) { | |||
73 | 85 | ||
74 | 86 | ||
75 | static void check (LexState *ls, int c) { | 87 | static void check (LexState *ls, int c) { |
76 | if (ls->token != c) | 88 | if (ls->t.token != c) |
77 | error_expected(ls, c); | 89 | error_expected(ls, c); |
78 | next(ls); | 90 | next(ls); |
79 | } | 91 | } |
@@ -90,7 +102,7 @@ static void setline (LexState *ls) { | |||
90 | 102 | ||
91 | 103 | ||
92 | static int optional (LexState *ls, int c) { | 104 | static int optional (LexState *ls, int c) { |
93 | if (ls->token == c) { | 105 | if (ls->t.token == c) { |
94 | next(ls); | 106 | next(ls); |
95 | return 1; | 107 | return 1; |
96 | } | 108 | } |
@@ -99,7 +111,7 @@ static int optional (LexState *ls, int c) { | |||
99 | 111 | ||
100 | 112 | ||
101 | static void check_match (LexState *ls, int what, int who, int where) { | 113 | static void check_match (LexState *ls, int what, int who, int where) { |
102 | if (ls->token != what) { | 114 | if (ls->t.token != what) { |
103 | if (where == ls->linenumber) | 115 | if (where == ls->linenumber) |
104 | error_expected(ls, what); | 116 | error_expected(ls, what); |
105 | else { | 117 | else { |
@@ -149,9 +161,9 @@ static void code_string (LexState *ls, TString *s) { | |||
149 | 161 | ||
150 | static int checkname (LexState *ls) { | 162 | static int checkname (LexState *ls) { |
151 | int sc; | 163 | int sc; |
152 | if (ls->token != TK_NAME) | 164 | if (ls->t.token != TK_NAME) |
153 | luaK_error(ls, "<name> expected"); | 165 | luaK_error(ls, "<name> expected"); |
154 | sc = string_constant(ls->fs, ls->seminfo.ts); | 166 | sc = string_constant(ls->fs, ls->t.seminfo.ts); |
155 | next(ls); | 167 | next(ls); |
156 | return sc; | 168 | return sc; |
157 | } | 169 | } |
@@ -164,7 +176,7 @@ static TString *str_checkname (LexState *ls) { | |||
164 | 176 | ||
165 | 177 | ||
166 | static TString *optionalname (LexState *ls) { | 178 | static TString *optionalname (LexState *ls) { |
167 | if (ls->token == TK_NAME) | 179 | if (ls->t.token == TK_NAME) |
168 | return str_checkname(ls); | 180 | return str_checkname(ls); |
169 | else | 181 | else |
170 | return NULL; | 182 | return NULL; |
@@ -296,6 +308,7 @@ static void adjust_mult_assign (LexState *ls, int nvars, int nexps) { | |||
296 | 308 | ||
297 | static void code_args (LexState *ls, int nparams, int dots) { | 309 | static void code_args (LexState *ls, int nparams, int dots) { |
298 | FuncState *fs = ls->fs; | 310 | FuncState *fs = ls->fs; |
311 | nparams -= dots; /* do not count `...' as a parameter */ | ||
299 | adjustlocalvars(ls, nparams); | 312 | adjustlocalvars(ls, nparams); |
300 | luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); | 313 | luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); |
301 | nparams = fs->nlocalvar; /* `self' could be there already */ | 314 | nparams = fs->nlocalvar; /* `self' could be there already */ |
@@ -310,19 +323,6 @@ static void code_args (LexState *ls, int nparams, int dots) { | |||
310 | } | 323 | } |
311 | 324 | ||
312 | 325 | ||
313 | static int getvarname (LexState *ls, expdesc *var) { | ||
314 | switch (var->k) { | ||
315 | case VGLOBAL: | ||
316 | return var->u.index; | ||
317 | case VLOCAL: | ||
318 | return string_constant(ls->fs, ls->fs->localvar[var->u.index]); | ||
319 | default: | ||
320 | error_unexpected(ls); /* there is no `var name' */ | ||
321 | return 0; /* to avoid warnings */ | ||
322 | } | ||
323 | } | ||
324 | |||
325 | |||
326 | static void enterbreak (FuncState *fs, Breaklabel *bl) { | 326 | static void enterbreak (FuncState *fs, Breaklabel *bl) { |
327 | bl->stacklevel = fs->stacklevel; | 327 | bl->stacklevel = fs->stacklevel; |
328 | bl->label = NULL; | 328 | bl->label = NULL; |
@@ -417,7 +417,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z) { | |||
417 | init_state(&lexstate, &funcstate, luaS_new(L, zname(z))); | 417 | init_state(&lexstate, &funcstate, luaS_new(L, zname(z))); |
418 | next(&lexstate); /* read first token */ | 418 | next(&lexstate); /* read first token */ |
419 | chunk(&lexstate); | 419 | chunk(&lexstate); |
420 | if (lexstate.token != TK_EOS) | 420 | if (lexstate.t.token != TK_EOS) |
421 | luaK_error(&lexstate, "<eof> expected"); | 421 | luaK_error(&lexstate, "<eof> expected"); |
422 | close_func(&lexstate); | 422 | close_func(&lexstate); |
423 | LUA_ASSERT(L, funcstate.prev == NULL, "wrong list end"); | 423 | LUA_ASSERT(L, funcstate.prev == NULL, "wrong list end"); |
@@ -436,7 +436,7 @@ static int explist1 (LexState *ls) { | |||
436 | int n = 1; /* at least one expression */ | 436 | int n = 1; /* at least one expression */ |
437 | expdesc v; | 437 | expdesc v; |
438 | expr(ls, &v); | 438 | expr(ls, &v); |
439 | while (ls->token == ',') { | 439 | while (ls->t.token == ',') { |
440 | luaK_tostack(ls, &v, 1); /* gets only 1 value from previous expression */ | 440 | luaK_tostack(ls, &v, 1); /* gets only 1 value from previous expression */ |
441 | next(ls); /* skip comma */ | 441 | next(ls); /* skip comma */ |
442 | expr(ls, &v); | 442 | expr(ls, &v); |
@@ -449,7 +449,7 @@ static int explist1 (LexState *ls) { | |||
449 | 449 | ||
450 | static int explist (LexState *ls) { | 450 | static int explist (LexState *ls) { |
451 | /* explist -> [ explist1 ] */ | 451 | /* explist -> [ explist1 ] */ |
452 | switch (ls->token) { | 452 | switch (ls->t.token) { |
453 | case TK_NUMBER: case TK_STRING: case TK_NIL: case '{': | 453 | case TK_NUMBER: case TK_STRING: case TK_NIL: case '{': |
454 | case TK_FUNCTION: case '(': case TK_NAME: case '%': | 454 | case TK_FUNCTION: case '(': case TK_NAME: case '%': |
455 | case TK_NOT: case '-': /* first `expr' */ | 455 | case TK_NOT: case '-': /* first `expr' */ |
@@ -463,7 +463,7 @@ static int explist (LexState *ls) { | |||
463 | static void funcargs (LexState *ls, int slf) { | 463 | static void funcargs (LexState *ls, int slf) { |
464 | FuncState *fs = ls->fs; | 464 | FuncState *fs = ls->fs; |
465 | int slevel = fs->stacklevel - slf - 1; /* where is func in the stack */ | 465 | int slevel = fs->stacklevel - slf - 1; /* where is func in the stack */ |
466 | switch (ls->token) { | 466 | switch (ls->t.token) { |
467 | case '(': { /* funcargs -> '(' explist ')' */ | 467 | case '(': { /* funcargs -> '(' explist ')' */ |
468 | int line = ls->linenumber; | 468 | int line = ls->linenumber; |
469 | int nargs; | 469 | int nargs; |
@@ -478,19 +478,19 @@ static void funcargs (LexState *ls, int slf) { | |||
478 | #endif | 478 | #endif |
479 | break; | 479 | break; |
480 | } | 480 | } |
481 | 481 | case '{': { /* funcargs -> constructor */ | |
482 | case '{': /* funcargs -> constructor */ | ||
483 | constructor(ls); | 482 | constructor(ls); |
484 | break; | 483 | break; |
485 | 484 | } | |
486 | case TK_STRING: /* funcargs -> STRING */ | 485 | case TK_STRING: { /* funcargs -> STRING */ |
487 | code_string(ls, ls->seminfo.ts); /* must use `seminfo' before `next' */ | 486 | code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ |
488 | next(ls); | 487 | next(ls); |
489 | break; | 488 | break; |
490 | 489 | } | |
491 | default: | 490 | default: { |
492 | luaK_error(ls, "function arguments expected"); | 491 | luaK_error(ls, "function arguments expected"); |
493 | break; | 492 | break; |
493 | } | ||
494 | } | 494 | } |
495 | fs->stacklevel = slevel; /* call will remove function and arguments */ | 495 | fs->stacklevel = slevel; /* call will remove function and arguments */ |
496 | luaK_code2(fs, OP_CALL, slevel, MULT_RET); | 496 | luaK_code2(fs, OP_CALL, slevel, MULT_RET); |
@@ -499,22 +499,22 @@ static void funcargs (LexState *ls, int slf) { | |||
499 | 499 | ||
500 | static void var_or_func_tail (LexState *ls, expdesc *v) { | 500 | static void var_or_func_tail (LexState *ls, expdesc *v) { |
501 | for (;;) { | 501 | for (;;) { |
502 | switch (ls->token) { | 502 | switch (ls->t.token) { |
503 | case '.': /* var_or_func_tail -> '.' NAME */ | 503 | case '.': { /* var_or_func_tail -> '.' NAME */ |
504 | next(ls); | 504 | next(ls); |
505 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | 505 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ |
506 | luaK_kstr(ls, checkname(ls)); | 506 | luaK_kstr(ls, checkname(ls)); |
507 | v->k = VINDEXED; | 507 | v->k = VINDEXED; |
508 | break; | 508 | break; |
509 | 509 | } | |
510 | case '[': /* var_or_func_tail -> '[' exp1 ']' */ | 510 | case '[': { /* var_or_func_tail -> '[' exp1 ']' */ |
511 | next(ls); | 511 | next(ls); |
512 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | 512 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ |
513 | v->k = VINDEXED; | 513 | v->k = VINDEXED; |
514 | exp1(ls); | 514 | exp1(ls); |
515 | check(ls, ']'); | 515 | check(ls, ']'); |
516 | break; | 516 | break; |
517 | 517 | } | |
518 | case ':': { /* var_or_func_tail -> ':' NAME funcargs */ | 518 | case ':': { /* var_or_func_tail -> ':' NAME funcargs */ |
519 | int name; | 519 | int name; |
520 | next(ls); | 520 | next(ls); |
@@ -526,14 +526,13 @@ static void var_or_func_tail (LexState *ls, expdesc *v) { | |||
526 | v->u.l.t = v->u.l.f = NO_JUMP; | 526 | v->u.l.t = v->u.l.f = NO_JUMP; |
527 | break; | 527 | break; |
528 | } | 528 | } |
529 | 529 | case '(': case TK_STRING: case '{': { /* var_or_func_tail -> funcargs */ | |
530 | case '(': case TK_STRING: case '{': /* var_or_func_tail -> funcargs */ | ||
531 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ | 530 | luaK_tostack(ls, v, 1); /* `v' must be on stack */ |
532 | funcargs(ls, 0); | 531 | funcargs(ls, 0); |
533 | v->k = VEXP; | 532 | v->k = VEXP; |
534 | v->u.l.t = v->u.l.f = NO_JUMP; | 533 | v->u.l.t = v->u.l.f = NO_JUMP; |
535 | break; | 534 | break; |
536 | 535 | } | |
537 | default: return; /* should be follow... */ | 536 | default: return; /* should be follow... */ |
538 | } | 537 | } |
539 | } | 538 | } |
@@ -563,17 +562,17 @@ static void var_or_func (LexState *ls, expdesc *v) { | |||
563 | 562 | ||
564 | static void recfield (LexState *ls) { | 563 | static void recfield (LexState *ls) { |
565 | /* recfield -> (NAME | '['exp1']') = exp1 */ | 564 | /* recfield -> (NAME | '['exp1']') = exp1 */ |
566 | switch (ls->token) { | 565 | switch (ls->t.token) { |
567 | case TK_NAME: | 566 | case TK_NAME: { |
568 | luaK_kstr(ls, checkname(ls)); | 567 | luaK_kstr(ls, checkname(ls)); |
569 | break; | 568 | break; |
570 | 569 | } | |
571 | case '[': | 570 | case '[': { |
572 | next(ls); | 571 | next(ls); |
573 | exp1(ls); | 572 | exp1(ls); |
574 | check(ls, ']'); | 573 | check(ls, ']'); |
575 | break; | 574 | break; |
576 | 575 | } | |
577 | default: luaK_error(ls, "<name> or `[' expected"); | 576 | default: luaK_error(ls, "<name> or `[' expected"); |
578 | } | 577 | } |
579 | check(ls, '='); | 578 | check(ls, '='); |
@@ -582,13 +581,14 @@ static void recfield (LexState *ls) { | |||
582 | 581 | ||
583 | 582 | ||
584 | static int recfields (LexState *ls) { | 583 | static int recfields (LexState *ls) { |
585 | /* recfields -> { ',' recfield } [','] */ | 584 | /* recfields -> recfield { ',' recfield } [','] */ |
586 | FuncState *fs = ls->fs; | 585 | FuncState *fs = ls->fs; |
587 | int n = 1; /* one has been read before */ | 586 | int n = 1; /* at least one element */ |
588 | int mod_n = 1; /* mod_n == n%RFIELDS_PER_FLUSH */ | 587 | int mod_n = 1; /* mod_n == n%RFIELDS_PER_FLUSH */ |
589 | while (ls->token == ',') { | 588 | recfield(ls); |
589 | while (ls->t.token == ',') { | ||
590 | next(ls); | 590 | next(ls); |
591 | if (ls->token == ';' || ls->token == '}') | 591 | if (ls->t.token == ';' || ls->t.token == '}') |
592 | break; | 592 | break; |
593 | recfield(ls); | 593 | recfield(ls); |
594 | n++; | 594 | n++; |
@@ -604,13 +604,14 @@ static int recfields (LexState *ls) { | |||
604 | 604 | ||
605 | 605 | ||
606 | static int listfields (LexState *ls) { | 606 | static int listfields (LexState *ls) { |
607 | /* listfields -> { ',' exp1 } [','] */ | 607 | /* listfields -> exp1 { ',' exp1 } [','] */ |
608 | FuncState *fs = ls->fs; | 608 | FuncState *fs = ls->fs; |
609 | int n = 1; /* one has been read before */ | 609 | int n = 1; /* at least one element */ |
610 | int mod_n = 1; /* mod_n == n%LFIELDS_PER_FLUSH */ | 610 | int mod_n = 1; /* mod_n == n%LFIELDS_PER_FLUSH */ |
611 | while (ls->token == ',') { | 611 | exp1(ls); |
612 | while (ls->t.token == ',') { | ||
612 | next(ls); | 613 | next(ls); |
613 | if (ls->token == ';' || ls->token == '}') | 614 | if (ls->t.token == ';' || ls->t.token == '}') |
614 | break; | 615 | break; |
615 | exp1(ls); | 616 | exp1(ls); |
616 | n++; | 617 | n++; |
@@ -629,41 +630,34 @@ static int listfields (LexState *ls) { | |||
629 | 630 | ||
630 | 631 | ||
631 | static void constructor_part (LexState *ls, Constdesc *cd) { | 632 | static void constructor_part (LexState *ls, Constdesc *cd) { |
632 | switch (ls->token) { | 633 | switch (ls->t.token) { |
633 | case ';': case '}': /* constructor_part -> empty */ | 634 | case ';': case '}': { /* constructor_part -> empty */ |
634 | cd->n = 0; | 635 | cd->n = 0; |
635 | cd->k = ls->token; | 636 | cd->k = ls->t.token; |
636 | return; | ||
637 | |||
638 | case TK_NAME: { | ||
639 | expdesc v; | ||
640 | expr(ls, &v); | ||
641 | if (ls->token == '=') { | ||
642 | luaK_kstr(ls, getvarname(ls, &v)); | ||
643 | next(ls); /* skip '=' */ | ||
644 | exp1(ls); | ||
645 | cd->n = recfields(ls); | ||
646 | cd->k = 1; /* record */ | ||
647 | } | ||
648 | else { | ||
649 | luaK_tostack(ls, &v, 1); | ||
650 | cd->n = listfields(ls); | ||
651 | cd->k = 0; /* list */ | ||
652 | } | ||
653 | break; | 637 | break; |
654 | } | 638 | } |
655 | 639 | case TK_NAME: { /* may be listfields or recfields */ | |
656 | case '[': /* constructor_part -> recfield recfields */ | 640 | Token current; |
657 | recfield(ls); | 641 | int nexttoken; /* to get the look ahead */ |
642 | current = ls->t; /* save for `unget' */ | ||
643 | next(ls); | ||
644 | nexttoken = ls->t.token; | ||
645 | ungettoken(ls, ¤t); | ||
646 | if (nexttoken != '=') /* expression? */ | ||
647 | goto case_default; | ||
648 | /* else go through to recfields */ | ||
649 | } | ||
650 | case '[': { /* constructor_part -> recfields */ | ||
658 | cd->n = recfields(ls); | 651 | cd->n = recfields(ls); |
659 | cd->k = 1; /* record */ | 652 | cd->k = 1; /* record */ |
660 | break; | 653 | break; |
661 | 654 | } | |
662 | default: /* constructor_part -> exp1 listfields */ | 655 | default: { /* constructor_part -> listfields */ |
663 | exp1(ls); | 656 | case_default: |
664 | cd->n = listfields(ls); | 657 | cd->n = listfields(ls); |
665 | cd->k = 0; /* list */ | 658 | cd->k = 0; /* list */ |
666 | break; | 659 | break; |
660 | } | ||
667 | } | 661 | } |
668 | } | 662 | } |
669 | 663 | ||
@@ -678,7 +672,7 @@ static void constructor (LexState *ls) { | |||
678 | check(ls, '{'); | 672 | check(ls, '{'); |
679 | constructor_part(ls, &cd); | 673 | constructor_part(ls, &cd); |
680 | nelems = cd.n; | 674 | nelems = cd.n; |
681 | if (ls->token == ';') { | 675 | if (ls->t.token == ';') { |
682 | Constdesc other_cd; | 676 | Constdesc other_cd; |
683 | next(ls); | 677 | next(ls); |
684 | constructor_part(ls, &other_cd); | 678 | constructor_part(ls, &other_cd); |
@@ -707,46 +701,46 @@ static void constructor (LexState *ls) { | |||
707 | static void simpleexp (LexState *ls, expdesc *v) { | 701 | static void simpleexp (LexState *ls, expdesc *v) { |
708 | FuncState *fs = ls->fs; | 702 | FuncState *fs = ls->fs; |
709 | setline(ls); | 703 | setline(ls); |
710 | switch (ls->token) { | 704 | switch (ls->t.token) { |
711 | case TK_NUMBER: { /* simpleexp -> NUMBER */ | 705 | case TK_NUMBER: { /* simpleexp -> NUMBER */ |
712 | Number r = ls->seminfo.r; | 706 | Number r = ls->t.seminfo.r; |
713 | next(ls); | 707 | next(ls); |
714 | luaK_number(fs, r); | 708 | luaK_number(fs, r); |
715 | break; | 709 | break; |
716 | } | 710 | } |
717 | 711 | case TK_STRING: { /* simpleexp -> STRING */ | |
718 | case TK_STRING: /* simpleexp -> STRING */ | 712 | code_string(ls, ls->t.seminfo.ts); /* must use `seminfo' before `next' */ |
719 | code_string(ls, ls->seminfo.ts); /* must use `seminfo' before `next' */ | ||
720 | next(ls); | 713 | next(ls); |
721 | break; | 714 | break; |
722 | 715 | } | |
723 | case TK_NIL: /* simpleexp -> NIL */ | 716 | case TK_NIL: { /* simpleexp -> NIL */ |
724 | luaK_adjuststack(fs, -1); | 717 | luaK_adjuststack(fs, -1); |
725 | next(ls); | 718 | next(ls); |
726 | break; | 719 | break; |
727 | 720 | } | |
728 | case '{': /* simpleexp -> constructor */ | 721 | case '{': { /* simpleexp -> constructor */ |
729 | constructor(ls); | 722 | constructor(ls); |
730 | break; | 723 | break; |
731 | 724 | } | |
732 | case TK_FUNCTION: /* simpleexp -> FUNCTION body */ | 725 | case TK_FUNCTION: { /* simpleexp -> FUNCTION body */ |
733 | next(ls); | 726 | next(ls); |
734 | body(ls, 0, ls->linenumber); | 727 | body(ls, 0, ls->linenumber); |
735 | break; | 728 | break; |
736 | 729 | } | |
737 | case '(': /* simpleexp -> '(' expr ')' */ | 730 | case '(': { /* simpleexp -> '(' expr ')' */ |
738 | next(ls); | 731 | next(ls); |
739 | expr(ls, v); | 732 | expr(ls, v); |
740 | check(ls, ')'); | 733 | check(ls, ')'); |
741 | return; | 734 | return; |
742 | 735 | } | |
743 | case TK_NAME: case '%': | 736 | case TK_NAME: case '%': { |
744 | var_or_func(ls, v); | 737 | var_or_func(ls, v); |
745 | return; | 738 | return; |
746 | 739 | } | |
747 | default: | 740 | default: { |
748 | luaK_error(ls, "<expression> expected"); | 741 | luaK_error(ls, "<expression> expected"); |
749 | return; | 742 | return; |
743 | } | ||
750 | } | 744 | } |
751 | v->k = VEXP; | 745 | v->k = VEXP; |
752 | v->u.l.t = v->u.l.f = NO_JUMP; | 746 | v->u.l.t = v->u.l.f = NO_JUMP; |
@@ -793,17 +787,17 @@ static int get_priority (int op, int *rp) { | |||
793 | */ | 787 | */ |
794 | static void subexpr (LexState *ls, expdesc *v, int limit) { | 788 | static void subexpr (LexState *ls, expdesc *v, int limit) { |
795 | int rp; | 789 | int rp; |
796 | if (ls->token == '-' || ls->token == TK_NOT) { | 790 | if (ls->t.token == '-' || ls->t.token == TK_NOT) { |
797 | int op = ls->token; /* operator */ | 791 | int op = ls->t.token; /* operator */ |
798 | next(ls); | 792 | next(ls); |
799 | subexpr(ls, v, UNARY_PRIORITY); | 793 | subexpr(ls, v, UNARY_PRIORITY); |
800 | luaK_prefix(ls, op, v); | 794 | luaK_prefix(ls, op, v); |
801 | } | 795 | } |
802 | else simpleexp(ls, v); | 796 | else simpleexp(ls, v); |
803 | /* expand while operators have priorities higher than `limit' */ | 797 | /* expand while operators have priorities higher than `limit' */ |
804 | while (get_priority(ls->token, &rp) > limit) { | 798 | while (get_priority(ls->t.token, &rp) > limit) { |
805 | expdesc v2; | 799 | expdesc v2; |
806 | int op = ls->token; /* current operator (with priority == `rp') */ | 800 | int op = ls->t.token; /* current operator (with priority == `rp') */ |
807 | next(ls); | 801 | next(ls); |
808 | luaK_infix(ls, op, v); | 802 | luaK_infix(ls, op, v); |
809 | subexpr(ls, &v2, rp); /* read sub-expression with priority > `rp' */ | 803 | subexpr(ls, &v2, rp); /* read sub-expression with priority > `rp' */ |
@@ -839,7 +833,7 @@ static void block (LexState *ls) { | |||
839 | static int assignment (LexState *ls, expdesc *v, int nvars) { | 833 | static int assignment (LexState *ls, expdesc *v, int nvars) { |
840 | int left = 0; | 834 | int left = 0; |
841 | luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); | 835 | luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment"); |
842 | if (ls->token == ',') { /* assignment -> ',' NAME assignment */ | 836 | if (ls->t.token == ',') { /* assignment -> ',' NAME assignment */ |
843 | expdesc nv; | 837 | expdesc nv; |
844 | next(ls); | 838 | next(ls); |
845 | var_or_func(ls, &nv); | 839 | var_or_func(ls, &nv); |
@@ -849,7 +843,7 @@ static int assignment (LexState *ls, expdesc *v, int nvars) { | |||
849 | } | 843 | } |
850 | else { /* assignment -> '=' explist1 */ | 844 | else { /* assignment -> '=' explist1 */ |
851 | int nexps;; | 845 | int nexps;; |
852 | if (ls->token != '=') | 846 | if (ls->t.token != '=') |
853 | error_unexpected(ls); | 847 | error_unexpected(ls); |
854 | next(ls); | 848 | next(ls); |
855 | nexps = explist1(ls); | 849 | nexps = explist1(ls); |
@@ -936,7 +930,7 @@ static void forlist (LexState *ls, TString *indexname) { | |||
936 | check(ls, ','); | 930 | check(ls, ','); |
937 | valname = str_checkname(ls); | 931 | valname = str_checkname(ls); |
938 | /* next test is dirty, but avoids `in' being a reserved word */ | 932 | /* next test is dirty, but avoids `in' being a reserved word */ |
939 | if (ls->token != TK_NAME || ls->seminfo.ts != luaS_new(ls->L, "in")) | 933 | if (ls->t.token != TK_NAME || ls->t.seminfo.ts != luaS_new(ls->L, "in")) |
940 | luaK_error(ls, "`in' expected"); | 934 | luaK_error(ls, "`in' expected"); |
941 | next(ls); /* skip `in' */ | 935 | next(ls); /* skip `in' */ |
942 | exp1(ls); /* table */ | 936 | exp1(ls); /* table */ |
@@ -959,7 +953,7 @@ static void forstat (LexState *ls, int line) { | |||
959 | enterbreak(fs, &bl); | 953 | enterbreak(fs, &bl); |
960 | setline_and_next(ls); /* skip `for' */ | 954 | setline_and_next(ls); /* skip `for' */ |
961 | varname = str_checkname(ls); /* first variable name */ | 955 | varname = str_checkname(ls); /* first variable name */ |
962 | switch (ls->token) { | 956 | switch (ls->t.token) { |
963 | case '=': fornum(ls, varname); break; | 957 | case '=': fornum(ls, varname); break; |
964 | case ',': forlist(ls, varname); break; | 958 | case ',': forlist(ls, varname); break; |
965 | default: luaK_error(ls, "`=' or `,' expected"); | 959 | default: luaK_error(ls, "`=' or `,' expected"); |
@@ -986,12 +980,12 @@ static void ifstat (LexState *ls, int line) { | |||
986 | expdesc v; | 980 | expdesc v; |
987 | int escapelist = NO_JUMP; | 981 | int escapelist = NO_JUMP; |
988 | test_and_block(ls, &v); /* IF cond THEN block */ | 982 | test_and_block(ls, &v); /* IF cond THEN block */ |
989 | while (ls->token == TK_ELSEIF) { | 983 | while (ls->t.token == TK_ELSEIF) { |
990 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 984 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
991 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 985 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); |
992 | test_and_block(ls, &v); /* ELSEIF cond THEN block */ | 986 | test_and_block(ls, &v); /* ELSEIF cond THEN block */ |
993 | } | 987 | } |
994 | if (ls->token == TK_ELSE) { | 988 | if (ls->t.token == TK_ELSE) { |
995 | luaK_concat(fs, &escapelist, luaK_jump(fs)); | 989 | luaK_concat(fs, &escapelist, luaK_jump(fs)); |
996 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); | 990 | luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs)); |
997 | setline_and_next(ls); /* skip ELSE */ | 991 | setline_and_next(ls); /* skip ELSE */ |
@@ -1008,7 +1002,7 @@ static int localnamelist (LexState *ls) { | |||
1008 | /* localnamelist -> NAME {',' NAME} */ | 1002 | /* localnamelist -> NAME {',' NAME} */ |
1009 | int i = 1; | 1003 | int i = 1; |
1010 | store_localvar(ls, str_checkname(ls), 0); | 1004 | store_localvar(ls, str_checkname(ls), 0); |
1011 | while (ls->token == ',') { | 1005 | while (ls->t.token == ',') { |
1012 | next(ls); | 1006 | next(ls); |
1013 | store_localvar(ls, str_checkname(ls), i++); | 1007 | store_localvar(ls, str_checkname(ls), i++); |
1014 | } | 1008 | } |
@@ -1018,7 +1012,7 @@ static int localnamelist (LexState *ls) { | |||
1018 | 1012 | ||
1019 | static int decinit (LexState *ls) { | 1013 | static int decinit (LexState *ls) { |
1020 | /* decinit -> ['=' explist1] */ | 1014 | /* decinit -> ['=' explist1] */ |
1021 | if (ls->token == '=') { | 1015 | if (ls->t.token == '=') { |
1022 | next(ls); | 1016 | next(ls); |
1023 | return explist1(ls); | 1017 | return explist1(ls); |
1024 | } | 1018 | } |
@@ -1043,8 +1037,8 @@ static int funcname (LexState *ls, expdesc *v) { | |||
1043 | /* funcname -> NAME [':' NAME | '.' NAME] */ | 1037 | /* funcname -> NAME [':' NAME | '.' NAME] */ |
1044 | int needself = 0; | 1038 | int needself = 0; |
1045 | singlevar(ls, str_checkname(ls), v, 0); | 1039 | singlevar(ls, str_checkname(ls), v, 0); |
1046 | if (ls->token == ':' || ls->token == '.') { | 1040 | if (ls->t.token == ':' || ls->t.token == '.') { |
1047 | needself = (ls->token == ':'); | 1041 | needself = (ls->t.token == ':'); |
1048 | next(ls); | 1042 | next(ls); |
1049 | luaK_tostack(ls, v, 1); | 1043 | luaK_tostack(ls, v, 1); |
1050 | luaK_kstr(ls, checkname(ls)); | 1044 | luaK_kstr(ls, checkname(ls)); |
@@ -1110,86 +1104,87 @@ static void breakstat (LexState *ls) { | |||
1110 | 1104 | ||
1111 | static int stat (LexState *ls) { | 1105 | static int stat (LexState *ls) { |
1112 | int line = ls->linenumber; /* may be needed for error messages */ | 1106 | int line = ls->linenumber; /* may be needed for error messages */ |
1113 | switch (ls->token) { | 1107 | switch (ls->t.token) { |
1114 | case TK_IF: /* stat -> ifstat */ | 1108 | case TK_IF: { /* stat -> ifstat */ |
1115 | ifstat(ls, line); | 1109 | ifstat(ls, line); |
1116 | return 1; | 1110 | return 1; |
1117 | 1111 | } | |
1118 | case TK_WHILE: /* stat -> whilestat */ | 1112 | case TK_WHILE: { /* stat -> whilestat */ |
1119 | whilestat(ls, line); | 1113 | whilestat(ls, line); |
1120 | return 1; | 1114 | return 1; |
1121 | 1115 | } | |
1122 | case TK_DO: /* stat -> DO block END */ | 1116 | case TK_DO: { /* stat -> DO block END */ |
1123 | setline_and_next(ls); /* skip DO */ | 1117 | setline_and_next(ls); /* skip DO */ |
1124 | block(ls); | 1118 | block(ls); |
1125 | check_END(ls, TK_DO, line); | 1119 | check_END(ls, TK_DO, line); |
1126 | return 1; | 1120 | return 1; |
1127 | 1121 | } | |
1128 | case TK_FOR: /* stat -> forstat */ | 1122 | case TK_FOR: { /* stat -> forstat */ |
1129 | forstat(ls, line); | 1123 | forstat(ls, line); |
1130 | return 1; | 1124 | return 1; |
1131 | 1125 | } | |
1132 | case TK_REPEAT: /* stat -> repeatstat */ | 1126 | case TK_REPEAT: { /* stat -> repeatstat */ |
1133 | repeatstat(ls, line); | 1127 | repeatstat(ls, line); |
1134 | return 1; | 1128 | return 1; |
1135 | 1129 | } | |
1136 | case TK_FUNCTION: /* stat -> funcstat */ | 1130 | case TK_FUNCTION: { /* stat -> funcstat */ |
1137 | funcstat(ls, line); | 1131 | funcstat(ls, line); |
1138 | return 1; | 1132 | return 1; |
1139 | 1133 | } | |
1140 | case TK_LOCAL: /* stat -> localstat */ | 1134 | case TK_LOCAL: { /* stat -> localstat */ |
1141 | localstat(ls); | 1135 | localstat(ls); |
1142 | return 1; | 1136 | return 1; |
1143 | 1137 | } | |
1144 | case TK_NAME: case '%': /* stat -> namestat */ | 1138 | case TK_NAME: case '%': { /* stat -> namestat */ |
1145 | namestat(ls); | 1139 | namestat(ls); |
1146 | return 1; | 1140 | return 1; |
1147 | 1141 | } | |
1148 | case TK_RETURN: /* stat -> retstat */ | 1142 | case TK_RETURN: { /* stat -> retstat */ |
1149 | retstat(ls); | 1143 | retstat(ls); |
1150 | return 2; /* must be last statement */ | 1144 | return 2; /* must be last statement */ |
1151 | 1145 | } | |
1152 | case TK_BREAK: /* stat -> breakstat */ | 1146 | case TK_BREAK: { /* stat -> breakstat */ |
1153 | breakstat(ls); | 1147 | breakstat(ls); |
1154 | return 2; /* must be last statement */ | 1148 | return 2; /* must be last statement */ |
1155 | 1149 | } | |
1156 | default: | 1150 | default: { |
1157 | return 0; /* no statement */ | 1151 | return 0; /* no statement */ |
1152 | } | ||
1153 | } | ||
1154 | } | ||
1155 | |||
1156 | |||
1157 | static int param (LexState *ls, int n) { | ||
1158 | /* param -> NAME | DOTS */ | ||
1159 | switch (ls->t.token) { | ||
1160 | case TK_DOTS: { | ||
1161 | next(ls); | ||
1162 | return 1; | ||
1163 | } | ||
1164 | case TK_NAME: { | ||
1165 | store_localvar(ls, str_checkname(ls), n); | ||
1166 | return 0; | ||
1167 | } | ||
1168 | default: { | ||
1169 | luaK_error(ls, "<name> or `...' expected"); | ||
1170 | return 0; /* to avoid warnings */ | ||
1171 | } | ||
1158 | } | 1172 | } |
1159 | } | 1173 | } |
1160 | 1174 | ||
1161 | 1175 | ||
1162 | static void parlist (LexState *ls) { | 1176 | static void parlist (LexState *ls) { |
1177 | /* parlist -> [ param { ',' param } ] */ | ||
1163 | int nparams = 0; | 1178 | int nparams = 0; |
1164 | int dots = 0; | 1179 | int dots = 0; |
1165 | switch (ls->token) { | 1180 | if (ls->t.token != ')') { /* is `parlist' not empty? */ |
1166 | case TK_DOTS: /* parlist -> DOTS */ | 1181 | dots = param(ls, nparams); |
1182 | nparams++; | ||
1183 | while (ls->t.token == ',' && !dots) { | ||
1167 | next(ls); | 1184 | next(ls); |
1168 | dots = 1; | 1185 | dots = param(ls, nparams); |
1169 | break; | 1186 | nparams++; |
1170 | 1187 | } | |
1171 | case TK_NAME: /* parlist, tailparlist -> NAME [',' tailparlist] */ | ||
1172 | init: | ||
1173 | store_localvar(ls, str_checkname(ls), nparams++); | ||
1174 | if (ls->token == ',') { | ||
1175 | next(ls); | ||
1176 | switch (ls->token) { | ||
1177 | case TK_DOTS: /* tailparlist -> DOTS */ | ||
1178 | next(ls); | ||
1179 | dots = 1; | ||
1180 | break; | ||
1181 | |||
1182 | case TK_NAME: /* tailparlist -> NAME [',' tailparlist] */ | ||
1183 | goto init; | ||
1184 | |||
1185 | default: luaK_error(ls, "<name> or `...' expected"); | ||
1186 | } | ||
1187 | } | ||
1188 | break; | ||
1189 | |||
1190 | case ')': break; /* parlist -> empty */ | ||
1191 | |||
1192 | default: luaK_error(ls, "<name> or `...' expected"); | ||
1193 | } | 1188 | } |
1194 | code_args(ls, nparams, dots); | 1189 | code_args(ls, nparams, dots); |
1195 | } | 1190 | } |