From a68635a919c5541b6acf5c2e8da5f81c67b65a7a Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 6 Apr 2001 15:25:00 -0300 Subject: list constructors do not adjust last expression --- lbaselib.c | 26 +++++++------------------- lcode.c | 8 +++----- ldebug.c | 10 +++++----- lopcodes.h | 6 +++--- lparser.c | 35 ++++++++++++++++++----------------- lvm.c | 19 ++++++++++--------- 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 @@ /* -** $Id: lbaselib.c,v 1.30 2001/03/07 12:43:52 roberto Exp roberto $ +** $Id: lbaselib.c,v 1.31 2001/03/26 14:31:49 roberto Exp roberto $ ** Basic library ** See Copyright Notice in lua.h */ @@ -366,30 +366,19 @@ static int luaB_require (lua_State *L) { } -static int luaB_pack (lua_State *L) { - int n = lua_gettop(L); - lua_newtable(L); - aux_setn(L, -3, n); - lua_insert(L, 1); - while (n) - lua_rawseti(L, 1, n--); - return 1; -} - - -static int aux_unpack (lua_State *L, int arg) { +static int aux_unwrap (lua_State *L, int arg) { int n, i; luaL_checktype(L, arg, LUA_TTABLE); n = lua_getn(L, arg); - luaL_checkstack(L, n, l_s("too many arguments")); + luaL_checkstack(L, n, l_s("table too big to unwrap")); for (i=1; i<=n; i++) /* push arg[1...n] */ lua_rawgeti(L, arg, i); return n; } -static int luaB_unpack (lua_State *L) { - return aux_unpack(L, 1); +static int luaB_unwrap (lua_State *L) { + return aux_unwrap(L, 1); } @@ -408,7 +397,7 @@ static int luaB_call (lua_State *L) { oldtop = lua_gettop(L); /* top before function-call preparation */ /* push function */ lua_pushvalue(L, 1); - n = aux_unpack(L, 2); /* push arg[1...n] */ + n = aux_unwrap(L, 2); /* push arg[1...n] */ status = lua_call(L, n, LUA_MULTRET); if (err != 0) { /* restore old error method */ lua_pushvalue(L, err); @@ -762,8 +751,7 @@ static const luaL_reg base_funcs[] = { {l_s("sort"), luaB_sort}, {l_s("tinsert"), luaB_tinsert}, {l_s("tremove"), luaB_tremove}, - {l_s("pack"), luaB_pack}, - {l_s("unpack"), luaB_unpack}, + {l_s("unwrap"), luaB_unwrap}, {l_s("xtype"), luaB_xtype}, }; diff --git a/lcode.c b/lcode.c index 72a1b71e..1b745d64 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.65 2001/03/07 13:22:55 roberto Exp roberto $ +** $Id: lcode.c,v 1.66 2001/03/26 14:31:49 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -474,13 +474,11 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { break; } case OP_SETLIST: { - if (arg2 == 0) return NO_JUMP; /* nothing to do */ - pop = arg2; + pop = fs->stacklevel - 1 - arg2; break; } case OP_SETMAP: { - if (arg1 == 0) return NO_JUMP; /* nothing to do */ - pop = 2*arg1; + pop = fs->stacklevel - 1 - arg1; break; } 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 @@ /* -** $Id: ldebug.c,v 1.74 2001/03/07 18:09:25 roberto Exp roberto $ +** $Id: ldebug.c,v 1.75 2001/03/26 14:31:49 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -419,13 +419,13 @@ static Instruction luaG_symbexec (lua_State *L, const Proto *pt, break; } case OP_SETLIST: { - pop = arg2; - check(top-pop >= 1); /* there must be a table below the list */ + check(arg2 >= 0); + pop = top-arg2-1; break; } case OP_SETMAP: { - pop = 2*arg1; - check(top-pop >= 1); + check(arg1 >= 0); + pop = top-arg1-1; break; } 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 @@ /* -** $Id: lopcodes.h,v 1.70 2001/01/15 16:13:24 roberto Exp roberto $ +** $Id: lopcodes.h,v 1.71 2001/03/07 13:22:55 roberto Exp roberto $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -110,8 +110,8 @@ OP_SETLOCAL,/* L x - LOC[l]=x */ OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */ OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */ -OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */ -OP_SETMAP,/* U v_u k_u - v_1 k_1 t t t[k_i]=v_i */ +OP_SETLIST,/* A B v_n-v_1 v_b v_b v_b[i+a*FPF]=v_i */ +OP_SETMAP,/* U v_n k_n - v_1 k_1 v_u v_u v_u[k_i]=v_i */ OP_ADD,/* - y x x+y */ OP_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 @@ /* -** $Id: lparser.c,v 1.140 2001/03/26 14:31:49 roberto Exp roberto $ +** $Id: lparser.c,v 1.141 2001/04/05 16:49:14 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -465,39 +465,40 @@ static void recfield (LexState *ls) { static int recfields (LexState *ls) { /* recfields -> recfield { `,' recfield } [`,'] */ FuncState *fs = ls->fs; + int t = fs->stacklevel-1; /* level of table on the stack */ int n = 1; /* at least one element */ recfield(ls); - while (ls->t.token == l_c(',')) { - next(ls); - if (ls->t.token == l_c(';') || ls->t.token == l_c('}')) - break; + while (ls->t.token == l_c(',') && + (next(ls), (ls->t.token != l_c(';') && ls->t.token != l_c('}')))) { + if (n%RFIELDS_PER_FLUSH == 0) + luaK_code1(fs, OP_SETMAP, t); recfield(ls); n++; - if (n%RFIELDS_PER_FLUSH == 0) - luaK_code1(fs, OP_SETMAP, RFIELDS_PER_FLUSH); } - luaK_code1(fs, OP_SETMAP, n%RFIELDS_PER_FLUSH); + luaK_code1(fs, OP_SETMAP, t); return n; } static int listfields (LexState *ls) { /* listfields -> exp1 { `,' exp1 } [`,'] */ + expdesc v; FuncState *fs = ls->fs; + int t = fs->stacklevel-1; /* level of table on the stack */ int n = 1; /* at least one element */ - exp1(ls); - while (ls->t.token == l_c(',')) { - next(ls); - if (ls->t.token == l_c(';') || ls->t.token == l_c('}')) - break; - exp1(ls); - n++; + expr(ls, &v); + while (ls->t.token == l_c(',') && + (next(ls), (ls->t.token != l_c(';') && ls->t.token != l_c('}')))) { + luaK_tostack(ls, &v, 1); /* only one value from intermediate expressions */ luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A, l_s("`item groups' in a list initializer")); if (n%LFIELDS_PER_FLUSH == 0) - luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); + luaK_code2(fs, OP_SETLIST, (n-1)/LFIELDS_PER_FLUSH, t); + expr(ls, &v); + n++; } - luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH); + luaK_tostack(ls, &v, 0); /* allow multiple values for last expression */ + luaK_code2(fs, OP_SETLIST, (n-1)/LFIELDS_PER_FLUSH, t); return n; } diff --git a/lvm.c b/lvm.c index 14f6feb3..9c1b13d0 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.176 2001/03/07 18:16:22 roberto Exp roberto $ +** $Id: lvm.c,v 1.177 2001/03/26 14:31:49 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -446,18 +446,19 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { } case OP_SETLIST: { int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; - int n = GETARG_B(i); - Hash *arr = hvalue(top-n-1); - for (; n; n--) - setobj(luaH_setnum(L, arr, n+aux), --top); + TObject *t = base+GETARG_B(i); + Hash *h = hvalue(t); + int n; + for (n = top-t-1; n; n--) + setobj(luaH_setnum(L, h, n+aux), --top); break; } case OP_SETMAP: { - int n = GETARG_U(i); - Hash *arr = hvalue((top-2*n)-1); - for (; n; n--) { + TObject *t = base+GETARG_U(i); + Hash *h = hvalue(t); + while (top-1 > t) { top-=2; - setobj(luaH_set(L, arr, top), top+1); + setobj(luaH_set(L, h, top), top+1); } break; } -- cgit v1.2.3-55-g6feb