aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-04-06 15:25:00 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-04-06 15:25:00 -0300
commita68635a919c5541b6acf5c2e8da5f81c67b65a7a (patch)
treee18acd4fc3fd6abdca5d3f8611e97015fd7bda0e
parent211214268065ec61180141d336e02393bc15bce4 (diff)
downloadlua-a68635a919c5541b6acf5c2e8da5f81c67b65a7a.tar.gz
lua-a68635a919c5541b6acf5c2e8da5f81c67b65a7a.tar.bz2
lua-a68635a919c5541b6acf5c2e8da5f81c67b65a7a.zip
list constructors do not adjust last expression
-rw-r--r--lbaselib.c26
-rw-r--r--lcode.c8
-rw-r--r--ldebug.c10
-rw-r--r--lopcodes.h6
-rw-r--r--lparser.c35
-rw-r--r--lvm.c19
6 files changed, 46 insertions, 58 deletions
diff --git a/lbaselib.c b/lbaselib.c
index d26bc7b0..d0dd1e9f 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.30 2001/03/07 12:43:52 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.31 2001/03/26 14:31:49 roberto Exp roberto $
3** Basic library 3** Basic library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -366,30 +366,19 @@ static int luaB_require (lua_State *L) {
366} 366}
367 367
368 368
369static int luaB_pack (lua_State *L) { 369static int aux_unwrap (lua_State *L, int arg) {
370 int n = lua_gettop(L);
371 lua_newtable(L);
372 aux_setn(L, -3, n);
373 lua_insert(L, 1);
374 while (n)
375 lua_rawseti(L, 1, n--);
376 return 1;
377}
378
379
380static int aux_unpack (lua_State *L, int arg) {
381 int n, i; 370 int n, i;
382 luaL_checktype(L, arg, LUA_TTABLE); 371 luaL_checktype(L, arg, LUA_TTABLE);
383 n = lua_getn(L, arg); 372 n = lua_getn(L, arg);
384 luaL_checkstack(L, n, l_s("too many arguments")); 373 luaL_checkstack(L, n, l_s("table too big to unwrap"));
385 for (i=1; i<=n; i++) /* push arg[1...n] */ 374 for (i=1; i<=n; i++) /* push arg[1...n] */
386 lua_rawgeti(L, arg, i); 375 lua_rawgeti(L, arg, i);
387 return n; 376 return n;
388} 377}
389 378
390 379
391static int luaB_unpack (lua_State *L) { 380static int luaB_unwrap (lua_State *L) {
392 return aux_unpack(L, 1); 381 return aux_unwrap(L, 1);
393} 382}
394 383
395 384
@@ -408,7 +397,7 @@ static int luaB_call (lua_State *L) {
408 oldtop = lua_gettop(L); /* top before function-call preparation */ 397 oldtop = lua_gettop(L); /* top before function-call preparation */
409 /* push function */ 398 /* push function */
410 lua_pushvalue(L, 1); 399 lua_pushvalue(L, 1);
411 n = aux_unpack(L, 2); /* push arg[1...n] */ 400 n = aux_unwrap(L, 2); /* push arg[1...n] */
412 status = lua_call(L, n, LUA_MULTRET); 401 status = lua_call(L, n, LUA_MULTRET);
413 if (err != 0) { /* restore old error method */ 402 if (err != 0) { /* restore old error method */
414 lua_pushvalue(L, err); 403 lua_pushvalue(L, err);
@@ -762,8 +751,7 @@ static const luaL_reg base_funcs[] = {
762 {l_s("sort"), luaB_sort}, 751 {l_s("sort"), luaB_sort},
763 {l_s("tinsert"), luaB_tinsert}, 752 {l_s("tinsert"), luaB_tinsert},
764 {l_s("tremove"), luaB_tremove}, 753 {l_s("tremove"), luaB_tremove},
765 {l_s("pack"), luaB_pack}, 754 {l_s("unwrap"), luaB_unwrap},
766 {l_s("unpack"), luaB_unpack},
767 {l_s("xtype"), luaB_xtype}, 755 {l_s("xtype"), luaB_xtype},
768}; 756};
769 757
diff --git a/lcode.c b/lcode.c
index 72a1b71e..1b745d64 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.65 2001/03/07 13:22:55 roberto Exp roberto $ 2** $Id: lcode.c,v 1.66 2001/03/26 14:31: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*/
@@ -474,13 +474,11 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
474 break; 474 break;
475 } 475 }
476 case OP_SETLIST: { 476 case OP_SETLIST: {
477 if (arg2 == 0) return NO_JUMP; /* nothing to do */ 477 pop = fs->stacklevel - 1 - arg2;
478 pop = arg2;
479 break; 478 break;
480 } 479 }
481 case OP_SETMAP: { 480 case OP_SETMAP: {
482 if (arg1 == 0) return NO_JUMP; /* nothing to do */ 481 pop = fs->stacklevel - 1 - arg1;
483 pop = 2*arg1;
484 break; 482 break;
485 } 483 }
486 case OP_PUSHNIL: { 484 case OP_PUSHNIL: {
diff --git a/ldebug.c b/ldebug.c
index 5f114f88..f8369d2d 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.74 2001/03/07 18:09:25 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.75 2001/03/26 14:31:49 roberto Exp roberto $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -419,13 +419,13 @@ static Instruction luaG_symbexec (lua_State *L, const Proto *pt,
419 break; 419 break;
420 } 420 }
421 case OP_SETLIST: { 421 case OP_SETLIST: {
422 pop = arg2; 422 check(arg2 >= 0);
423 check(top-pop >= 1); /* there must be a table below the list */ 423 pop = top-arg2-1;
424 break; 424 break;
425 } 425 }
426 case OP_SETMAP: { 426 case OP_SETMAP: {
427 pop = 2*arg1; 427 check(arg1 >= 0);
428 check(top-pop >= 1); 428 pop = top-arg1-1;
429 break; 429 break;
430 } 430 }
431 case OP_CONCAT: { 431 case OP_CONCAT: {
diff --git a/lopcodes.h b/lopcodes.h
index 207627a5..3b743880 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.70 2001/01/15 16:13:24 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.71 2001/03/07 13:22:55 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -110,8 +110,8 @@ OP_SETLOCAL,/* L x - LOC[l]=x */
110OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */ 110OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */
111OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */ 111OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */
112 112
113OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */ 113OP_SETLIST,/* A B v_n-v_1 v_b v_b v_b[i+a*FPF]=v_i */
114OP_SETMAP,/* U v_u k_u - v_1 k_1 t t t[k_i]=v_i */ 114OP_SETMAP,/* U v_n k_n - v_1 k_1 v_u v_u v_u[k_i]=v_i */
115 115
116OP_ADD,/* - y x x+y */ 116OP_ADD,/* - y x x+y */
117OP_ADDI,/* S x x+s */ 117OP_ADDI,/* S x x+s */
diff --git a/lparser.c b/lparser.c
index f01440ac..a5a56829 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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) {
465static int recfields (LexState *ls) { 465static 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
484static int listfields (LexState *ls) { 483static 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
diff --git a/lvm.c b/lvm.c
index 14f6feb3..9c1b13d0 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.176 2001/03/07 18:16:22 roberto Exp roberto $ 2** $Id: lvm.c,v 1.177 2001/03/26 14:31:49 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -446,18 +446,19 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
446 } 446 }
447 case OP_SETLIST: { 447 case OP_SETLIST: {
448 int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; 448 int aux = GETARG_A(i) * LFIELDS_PER_FLUSH;
449 int n = GETARG_B(i); 449 TObject *t = base+GETARG_B(i);
450 Hash *arr = hvalue(top-n-1); 450 Hash *h = hvalue(t);
451 for (; n; n--) 451 int n;
452 setobj(luaH_setnum(L, arr, n+aux), --top); 452 for (n = top-t-1; n; n--)
453 setobj(luaH_setnum(L, h, n+aux), --top);
453 break; 454 break;
454 } 455 }
455 case OP_SETMAP: { 456 case OP_SETMAP: {
456 int n = GETARG_U(i); 457 TObject *t = base+GETARG_U(i);
457 Hash *arr = hvalue((top-2*n)-1); 458 Hash *h = hvalue(t);
458 for (; n; n--) { 459 while (top-1 > t) {
459 top-=2; 460 top-=2;
460 setobj(luaH_set(L, arr, top), top+1); 461 setobj(luaH_set(L, h, top), top+1);
461 } 462 }
462 break; 463 break;
463 } 464 }