diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-04-06 15:25:00 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-04-06 15:25:00 -0300 |
commit | a68635a919c5541b6acf5c2e8da5f81c67b65a7a (patch) | |
tree | e18acd4fc3fd6abdca5d3f8611e97015fd7bda0e /lparser.c | |
parent | 211214268065ec61180141d336e02393bc15bce4 (diff) | |
download | lua-a68635a919c5541b6acf5c2e8da5f81c67b65a7a.tar.gz lua-a68635a919c5541b6acf5c2e8da5f81c67b65a7a.tar.bz2 lua-a68635a919c5541b6acf5c2e8da5f81c67b65a7a.zip |
list constructors do not adjust last expression
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 35 |
1 files changed, 18 insertions, 17 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.140 2001/03/26 14:31:49 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.141 2001/04/05 16:49:14 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 | */ |
@@ -465,39 +465,40 @@ static void recfield (LexState *ls) { | |||
465 | static int recfields (LexState *ls) { | 465 | static int recfields (LexState *ls) { |
466 | /* recfields -> recfield { `,' recfield } [`,'] */ | 466 | /* recfields -> recfield { `,' recfield } [`,'] */ |
467 | FuncState *fs = ls->fs; | 467 | FuncState *fs = ls->fs; |
468 | int t = fs->stacklevel-1; /* level of table on the stack */ | ||
468 | int n = 1; /* at least one element */ | 469 | int n = 1; /* at least one element */ |
469 | recfield(ls); | 470 | recfield(ls); |
470 | while (ls->t.token == l_c(',')) { | 471 | while (ls->t.token == l_c(',') && |
471 | next(ls); | 472 | (next(ls), (ls->t.token != l_c(';') && ls->t.token != l_c('}')))) { |
472 | if (ls->t.token == l_c(';') || ls->t.token == l_c('}')) | 473 | if (n%RFIELDS_PER_FLUSH == 0) |
473 | break; | 474 | luaK_code1(fs, OP_SETMAP, t); |
474 | recfield(ls); | 475 | recfield(ls); |
475 | n++; | 476 | n++; |
476 | if (n%RFIELDS_PER_FLUSH == 0) | ||
477 | luaK_code1(fs, OP_SETMAP, RFIELDS_PER_FLUSH); | ||
478 | } | 477 | } |
479 | luaK_code1(fs, OP_SETMAP, n%RFIELDS_PER_FLUSH); | 478 | luaK_code1(fs, OP_SETMAP, t); |
480 | return n; | 479 | return n; |
481 | } | 480 | } |
482 | 481 | ||
483 | 482 | ||
484 | static int listfields (LexState *ls) { | 483 | static int listfields (LexState *ls) { |
485 | /* listfields -> exp1 { `,' exp1 } [`,'] */ | 484 | /* listfields -> exp1 { `,' exp1 } [`,'] */ |
485 | expdesc v; | ||
486 | FuncState *fs = ls->fs; | 486 | FuncState *fs = ls->fs; |
487 | int t = fs->stacklevel-1; /* level of table on the stack */ | ||
487 | int n = 1; /* at least one element */ | 488 | int n = 1; /* at least one element */ |
488 | exp1(ls); | 489 | expr(ls, &v); |
489 | while (ls->t.token == l_c(',')) { | 490 | while (ls->t.token == l_c(',') && |
490 | next(ls); | 491 | (next(ls), (ls->t.token != l_c(';') && ls->t.token != l_c('}')))) { |
491 | if (ls->t.token == l_c(';') || ls->t.token == l_c('}')) | 492 | luaK_tostack(ls, &v, 1); /* only one value from intermediate expressions */ |
492 | break; | ||
493 | exp1(ls); | ||
494 | n++; | ||
495 | luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A, | 493 | luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A, |
496 | l_s("`item groups' in a list initializer")); | 494 | l_s("`item groups' in a list initializer")); |
497 | if (n%LFIELDS_PER_FLUSH == 0) | 495 | if (n%LFIELDS_PER_FLUSH == 0) |
498 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); | 496 | luaK_code2(fs, OP_SETLIST, (n-1)/LFIELDS_PER_FLUSH, t); |
497 | expr(ls, &v); | ||
498 | n++; | ||
499 | } | 499 | } |
500 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH); | 500 | luaK_tostack(ls, &v, 0); /* allow multiple values for last expression */ |
501 | luaK_code2(fs, OP_SETLIST, (n-1)/LFIELDS_PER_FLUSH, t); | ||
501 | return n; | 502 | return n; |
502 | } | 503 | } |
503 | 504 | ||