diff options
| -rw-r--r-- | lparser.c | 60 |
1 files changed, 34 insertions, 26 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 2.69 2009/10/11 20:02:19 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.70 2009/10/13 19:35:42 roberto Exp roberto $ |
| 3 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -440,8 +440,8 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, Varlist *varl, | |||
| 440 | /*============================================================*/ | 440 | /*============================================================*/ |
| 441 | 441 | ||
| 442 | 442 | ||
| 443 | static void field (LexState *ls, expdesc *v) { | 443 | static void fieldsel (LexState *ls, expdesc *v) { |
| 444 | /* field -> ['.' | ':'] NAME */ | 444 | /* fieldsel -> ['.' | ':'] NAME */ |
| 445 | FuncState *fs = ls->fs; | 445 | FuncState *fs = ls->fs; |
| 446 | expdesc key; | 446 | expdesc key; |
| 447 | luaK_exp2anyreg(fs, v); | 447 | luaK_exp2anyreg(fs, v); |
| @@ -524,6 +524,7 @@ static void lastlistfield (FuncState *fs, struct ConsControl *cc) { | |||
| 524 | 524 | ||
| 525 | 525 | ||
| 526 | static void listfield (LexState *ls, struct ConsControl *cc) { | 526 | static void listfield (LexState *ls, struct ConsControl *cc) { |
| 527 | /* listfield -> exp */ | ||
| 527 | expr(ls, &cc->v); | 528 | expr(ls, &cc->v); |
| 528 | luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); | 529 | luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); |
| 529 | cc->na++; | 530 | cc->na++; |
| @@ -531,8 +532,31 @@ static void listfield (LexState *ls, struct ConsControl *cc) { | |||
| 531 | } | 532 | } |
| 532 | 533 | ||
| 533 | 534 | ||
| 535 | static void field (LexState *ls, struct ConsControl *cc) { | ||
| 536 | /* field -> listfield | recfield */ | ||
| 537 | switch(ls->t.token) { | ||
| 538 | case TK_NAME: { /* may be 'listfield' or 'recfield' */ | ||
| 539 | if (luaX_lookahead(ls) != '=') /* expression? */ | ||
| 540 | listfield(ls, cc); | ||
| 541 | else | ||
| 542 | recfield(ls, cc); | ||
| 543 | break; | ||
| 544 | } | ||
| 545 | case '[': { | ||
| 546 | recfield(ls, cc); | ||
| 547 | break; | ||
| 548 | } | ||
| 549 | default: { | ||
| 550 | listfield(ls, cc); | ||
| 551 | break; | ||
| 552 | } | ||
| 553 | } | ||
| 554 | } | ||
| 555 | |||
| 556 | |||
| 534 | static void constructor (LexState *ls, expdesc *t) { | 557 | static void constructor (LexState *ls, expdesc *t) { |
| 535 | /* constructor -> ?? */ | 558 | /* constructor -> '{' [ field { sep field } [sep] ] '}' |
| 559 | sep -> ',' | ';' */ | ||
| 536 | FuncState *fs = ls->fs; | 560 | FuncState *fs = ls->fs; |
| 537 | int line = ls->linenumber; | 561 | int line = ls->linenumber; |
| 538 | int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); | 562 | int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); |
| @@ -547,23 +571,7 @@ static void constructor (LexState *ls, expdesc *t) { | |||
| 547 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); | 571 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); |
| 548 | if (ls->t.token == '}') break; | 572 | if (ls->t.token == '}') break; |
| 549 | closelistfield(fs, &cc); | 573 | closelistfield(fs, &cc); |
| 550 | switch(ls->t.token) { | 574 | field(ls, &cc); |
| 551 | case TK_NAME: { /* may be listfields or recfields */ | ||
| 552 | if (luaX_lookahead(ls) != '=') /* expression? */ | ||
| 553 | listfield(ls, &cc); | ||
| 554 | else | ||
| 555 | recfield(ls, &cc); | ||
| 556 | break; | ||
| 557 | } | ||
| 558 | case '[': { /* constructor_item -> recfield */ | ||
| 559 | recfield(ls, &cc); | ||
| 560 | break; | ||
| 561 | } | ||
| 562 | default: { /* constructor_part -> listfield */ | ||
| 563 | listfield(ls, &cc); | ||
| 564 | break; | ||
| 565 | } | ||
| 566 | } | ||
| 567 | } while (testnext(ls, ',') || testnext(ls, ';')); | 575 | } while (testnext(ls, ',') || testnext(ls, ';')); |
| 568 | check_match(ls, '}', '{', line); | 576 | check_match(ls, '}', '{', line); |
| 569 | lastlistfield(fs, &cc); | 577 | lastlistfield(fs, &cc); |
| @@ -725,8 +733,8 @@ static void primaryexp (LexState *ls, expdesc *v) { | |||
| 725 | prefixexp(ls, v); | 733 | prefixexp(ls, v); |
| 726 | for (;;) { | 734 | for (;;) { |
| 727 | switch (ls->t.token) { | 735 | switch (ls->t.token) { |
| 728 | case '.': { /* field */ | 736 | case '.': { /* fieldsel */ |
| 729 | field(ls, v); | 737 | fieldsel(ls, v); |
| 730 | break; | 738 | break; |
| 731 | } | 739 | } |
| 732 | case '[': { /* `[' exp1 `]' */ | 740 | case '[': { /* `[' exp1 `]' */ |
| @@ -1233,14 +1241,14 @@ static void localstat (LexState *ls) { | |||
| 1233 | 1241 | ||
| 1234 | 1242 | ||
| 1235 | static int funcname (LexState *ls, expdesc *v) { | 1243 | static int funcname (LexState *ls, expdesc *v) { |
| 1236 | /* funcname -> NAME {field} [`:' NAME] */ | 1244 | /* funcname -> NAME {fieldsel} [`:' NAME] */ |
| 1237 | int needself = 0; | 1245 | int needself = 0; |
| 1238 | singlevar(ls, v); | 1246 | singlevar(ls, v); |
| 1239 | while (ls->t.token == '.') | 1247 | while (ls->t.token == '.') |
| 1240 | field(ls, v); | 1248 | fieldsel(ls, v); |
| 1241 | if (ls->t.token == ':') { | 1249 | if (ls->t.token == ':') { |
| 1242 | needself = 1; | 1250 | needself = 1; |
| 1243 | field(ls, v); | 1251 | fieldsel(ls, v); |
| 1244 | } | 1252 | } |
| 1245 | return needself; | 1253 | return needself; |
| 1246 | } | 1254 | } |
