diff options
| -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 | } |
