mirror of
https://github.com/lua/lua
synced 2024-12-24 03:16:50 +03:00
new implementation for `next'
This commit is contained in:
parent
a290b84c67
commit
100bfec39a
35
lapi.c
35
lapi.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lapi.c,v 1.89 2000/08/29 14:52:27 roberto Exp roberto $
|
||||
** $Id: lapi.c,v 1.90 2000/08/29 20:43:28 roberto Exp roberto $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -327,7 +327,7 @@ int lua_ref (lua_State *L, int lock) {
|
||||
|
||||
|
||||
/*
|
||||
** miscelaneous functions
|
||||
** miscellaneous functions
|
||||
*/
|
||||
|
||||
|
||||
@ -359,24 +359,21 @@ void lua_unref (lua_State *L, int ref) {
|
||||
}
|
||||
|
||||
|
||||
int luaA_next (lua_State *L, const Hash *t, int i) {
|
||||
int tsize = t->size;
|
||||
for (; i<tsize; i++) {
|
||||
Node *n = node(t, i);
|
||||
if (ttype(val(n)) != TAG_NIL) {
|
||||
luaA_pushobject(L, key(n));
|
||||
luaA_pushobject(L, val(n));
|
||||
return i+1; /* index to be used next time */
|
||||
}
|
||||
}
|
||||
return 0; /* no more elements */
|
||||
}
|
||||
|
||||
|
||||
int lua_next (lua_State *L, int index, int i) {
|
||||
const TObject *t = Index(L, index);
|
||||
int lua_next (lua_State *L) {
|
||||
const TObject *t = Index(L, -2);
|
||||
Node *n;
|
||||
if (ttype(t) != TAG_TABLE)
|
||||
lua_error(L, "Lua API error - object is not a table in `lua_next'");
|
||||
return luaA_next(L, hvalue(t), i);
|
||||
n = luaH_next(L, hvalue(t), Index(L, -1));
|
||||
if (n) {
|
||||
*(L->top-1) = *key(n);
|
||||
*L->top = *val(n);
|
||||
api_incr_top(L);
|
||||
return 1;
|
||||
}
|
||||
else { /* no more elements */
|
||||
L->top -= 2; /* remove key and table */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
3
lapi.h
3
lapi.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lapi.h,v 1.18 2000/05/08 20:49:05 roberto Exp roberto $
|
||||
** $Id: lapi.h,v 1.19 2000/08/28 17:57:04 roberto Exp roberto $
|
||||
** Auxiliary functions from Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -13,6 +13,5 @@
|
||||
|
||||
TObject *luaA_index (lua_State *L, int index);
|
||||
void luaA_pushobject (lua_State *L, const TObject *o);
|
||||
int luaA_next (lua_State *L, const Hash *t, int i);
|
||||
|
||||
#endif
|
||||
|
31
lbuiltin.c
31
lbuiltin.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lbuiltin.c,v 1.123 2000/08/29 14:33:31 roberto Exp roberto $
|
||||
** $Id: lbuiltin.c,v 1.124 2000/08/29 14:41:56 roberto Exp roberto $
|
||||
** Built-in functions
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -267,6 +267,18 @@ int luaB_type (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int luaB_next (lua_State *L) {
|
||||
luaL_checktype(L, 1, "table");
|
||||
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
|
||||
if (lua_next(L))
|
||||
return 2;
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
@ -355,23 +367,6 @@ int luaB_call (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
int luaB_next (lua_State *L) {
|
||||
const Hash *a = gettable(L, 1);
|
||||
int i; /* `luaA_next' gets first element after `i' */
|
||||
if (lua_isnull(L, 2) || lua_isnil(L, 2)) /* no index or nil index? */
|
||||
i = 0; /* get first */
|
||||
else {
|
||||
i = luaH_pos(L, a, luaA_index(L, 2))+1;
|
||||
luaL_arg_check(L, i != 0, 2, "key not found");
|
||||
}
|
||||
if (luaA_next(L, a, i) != 0)
|
||||
return 2; /* `luaA_next' left them on the stack */
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int luaB_tostring (lua_State *L) {
|
||||
char buff[64];
|
||||
|
6
lcode.c
6
lcode.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lcode.c,v 1.48 2000/08/14 17:46:27 roberto Exp roberto $
|
||||
** $Id: lcode.c,v 1.49 2000/08/15 13:18:28 roberto Exp roberto $
|
||||
** Code generator for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -693,8 +693,8 @@ const struct OpProperties luaK_opproperties[NUM_OPCODES] = {
|
||||
{iO, 0, 0}, /* OP_PUSHNILJMP */
|
||||
{iS, 0, 0}, /* OP_FORPREP */
|
||||
{iS, 0, 3}, /* OP_FORLOOP */
|
||||
{iS, 3, 0}, /* OP_LFORPREP */
|
||||
{iS, 0, 4}, /* OP_LFORLOOP */
|
||||
{iS, 2, 0}, /* OP_LFORPREP */
|
||||
{iS, 0, 3}, /* OP_LFORLOOP */
|
||||
{iAB, VD, 0} /* OP_CLOSURE */
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lparser.c,v 1.109 2000/08/15 13:18:28 roberto Exp roberto $
|
||||
** $Id: lparser.c,v 1.110 2000/08/22 17:44:17 roberto Exp roberto $
|
||||
** LL(1) Parser and code generator for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -877,10 +877,9 @@ static void forlist (LexState *ls, TString *indexname) {
|
||||
next(ls); /* skip `in' */
|
||||
exp1(ls); /* table */
|
||||
new_localvarstr(ls, "*table*", 0);
|
||||
new_localvarstr(ls, "*counter*", 1);
|
||||
new_localvar(ls, indexname, 2);
|
||||
new_localvar(ls, valname, 3);
|
||||
forbody(ls, 4, OP_LFORPREP, OP_LFORLOOP);
|
||||
new_localvar(ls, indexname, 1);
|
||||
new_localvar(ls, valname, 2);
|
||||
forbody(ls, 3, OP_LFORPREP, OP_LFORLOOP);
|
||||
}
|
||||
|
||||
|
||||
|
24
ltable.c
24
ltable.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltable.c,v 1.52 2000/08/07 20:21:34 roberto Exp roberto $
|
||||
** $Id: ltable.c,v 1.53 2000/08/09 19:16:57 roberto Exp roberto $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -114,12 +114,26 @@ const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key) {
|
||||
}
|
||||
|
||||
|
||||
int luaH_pos (lua_State *L, const Hash *t, const TObject *key) {
|
||||
const TObject *v = luaH_get(L, t, key);
|
||||
return (v == &luaO_nilobject) ? -1 : /* key not found */
|
||||
(int)(((const char *)v - (const char *)(&t->node[0].val))/sizeof(Node));
|
||||
Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) {
|
||||
int i;
|
||||
if (ttype(key) == TAG_NIL)
|
||||
i = 0; /* first iteration */
|
||||
else {
|
||||
const TObject *v = luaH_get(L, t, key);
|
||||
if (v == &luaO_nilobject)
|
||||
lua_error(L, "invalid key for `next'");
|
||||
i = (int)(((const char *)v -
|
||||
(const char *)(&t->node[0].val)) / sizeof(Node)) + 1;
|
||||
}
|
||||
for (; i<t->size; i++) {
|
||||
Node *n = node(t, i);
|
||||
if (ttype(val(n)) != TAG_NIL)
|
||||
return n;
|
||||
}
|
||||
return NULL; /* no more elements */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** try to remove a key without value from a table. To avoid problems with
|
||||
** hash, change `key' for a number with the same hash.
|
||||
|
4
ltable.h
4
ltable.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltable.h,v 1.22 2000/06/05 20:15:33 roberto Exp roberto $
|
||||
** $Id: ltable.h,v 1.23 2000/06/06 16:31:41 roberto Exp roberto $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -21,7 +21,7 @@ const TObject *luaH_getnum (const Hash *t, Number key);
|
||||
const TObject *luaH_getstr (const Hash *t, TString *key);
|
||||
void luaH_remove (Hash *t, TObject *key);
|
||||
TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
|
||||
int luaH_pos (lua_State *L, const Hash *t, const TObject *r);
|
||||
Node * luaH_next (lua_State *L, const Hash *t, const TObject *r);
|
||||
TObject *luaH_setint (lua_State *L, Hash *t, int key);
|
||||
void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val);
|
||||
unsigned long luaH_hash (lua_State *L, const TObject *key);
|
||||
|
7
lua.h
7
lua.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lua.h,v 1.61 2000/08/29 14:33:31 roberto Exp roberto $
|
||||
** $Id: lua.h,v 1.62 2000/08/29 20:43:28 roberto Exp roberto $
|
||||
** Lua - An Extensible Extension Language
|
||||
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
|
||||
** e-mail: lua@tecgraf.puc-rio.br
|
||||
@ -29,6 +29,7 @@
|
||||
#define LUA_REFNIL (-1)
|
||||
|
||||
#define LUA_ANYTAG (-1)
|
||||
#define LUA_NOTAG (-2)
|
||||
|
||||
#define LUA_MULTRET (-1)
|
||||
|
||||
@ -129,7 +130,7 @@ int lua_dobuffer (lua_State *L, const char *buff, size_t size,
|
||||
|
||||
|
||||
/*
|
||||
** miscelaneous functions
|
||||
** miscellaneous functions
|
||||
*/
|
||||
int lua_newtag (lua_State *L);
|
||||
int lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
|
||||
@ -141,7 +142,7 @@ void lua_unref (lua_State *L, int ref);
|
||||
|
||||
long lua_collectgarbage (lua_State *L, long limit);
|
||||
|
||||
int lua_next (lua_State *L, int index, int i);
|
||||
int lua_next (lua_State *L);
|
||||
|
||||
|
||||
|
||||
|
32
lvm.c
32
lvm.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lvm.c,v 1.130 2000/08/29 14:41:56 roberto Exp roberto $
|
||||
** $Id: lvm.c,v 1.131 2000/08/29 14:48:16 roberto Exp roberto $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -656,34 +656,30 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
|
||||
break;
|
||||
}
|
||||
case OP_LFORPREP: {
|
||||
Node *node;
|
||||
if (ttype(top-1) != TAG_TABLE)
|
||||
lua_error(L, "`for' table must be a table");
|
||||
top++; /* counter */
|
||||
L->top = top;
|
||||
ttype(top-1) = TAG_NUMBER;
|
||||
nvalue(top-1) = (Number)luaA_next(L, hvalue(top-2), 0); /* counter */
|
||||
if (nvalue(top-1) == 0) { /* `empty' loop? */
|
||||
top -= 2; /* remove table and counter */
|
||||
node = luaH_next(L, hvalue(top-1), &luaO_nilobject);
|
||||
if (node == NULL) { /* `empty' loop? */
|
||||
top--; /* remove table */
|
||||
pc += GETARG_S(i)+1; /* jump to loop end */
|
||||
}
|
||||
else {
|
||||
top += 2; /* index,value */
|
||||
LUA_ASSERT(top==L->top, "bad top");
|
||||
*(top-2) = *key(node);
|
||||
*(top-1) = *val(node);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_LFORLOOP: {
|
||||
int n;
|
||||
top -= 2; /* remove old index,value */
|
||||
LUA_ASSERT(ttype(top-2) == TAG_TABLE, "invalid table");
|
||||
LUA_ASSERT(ttype(top-1) == TAG_NUMBER, "invalid counter");
|
||||
L->top = top;
|
||||
n = luaA_next(L, hvalue(top-2), (int)nvalue(top-1));
|
||||
if (n == 0) /* end loop? */
|
||||
top -= 2; /* remove table and counter */
|
||||
Node *node;
|
||||
LUA_ASSERT(ttype(top-3) == TAG_TABLE, "invalid table");
|
||||
node = luaH_next(L, hvalue(top-3), top-2);
|
||||
if (node == NULL) /* end loop? */
|
||||
top -= 3; /* remove table, key, and value */
|
||||
else {
|
||||
nvalue(top-1) = (Number)n;
|
||||
top += 2; /* new index,value */
|
||||
*(top-2) = *key(node);
|
||||
*(top-1) = *val(node);
|
||||
pc += GETARG_S(i); /* repeat loop */
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user