commit f04c83e0759b1059545ea0526c5999c35cb1793f
parent c364e9f97ee825be833d50a04a621d58d71af684
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Tue, 23 Feb 1999 11:57:06 -0300
new function "lua_next" (+ new implementation for "next")
Diffstat:
M | lapi.c | | | 64 | ++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
M | lapi.h | | | 3 | ++- |
M | lbuiltin.c | | | 172 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
M | ltable.c | | | 28 | +++++----------------------- |
M | ltable.h | | | 4 | ++-- |
M | lua.h | | | 4 | +++- |
6 files changed, 143 insertions(+), 132 deletions(-)
diff --git a/lapi.c b/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 1.36 1999/02/12 19:23:02 roberto Exp roberto $
+** $Id: lapi.c,v 1.37 1999/02/22 19:13:12 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -25,7 +25,7 @@
char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
- "$Autores: " LUA_AUTHORS " $";
+ "$Authors: " LUA_AUTHORS " $";
@@ -70,12 +70,8 @@ void luaA_packresults (void)
}
-int luaA_passresults (void)
-{
- luaD_checkstack(L->Cstack.num);
- memcpy(L->stack.top, L->Cstack.lua2C+L->stack.stack,
- L->Cstack.num*sizeof(TObject));
- L->stack.top += L->Cstack.num;
+int luaA_passresults (void) {
+ L->Cstack.base = L->Cstack.lua2C; /* position of first result */
return L->Cstack.num;
}
@@ -87,24 +83,29 @@ static void checkCparams (int nParams)
}
-static lua_Object put_luaObject (TObject *o)
-{
+static lua_Object put_luaObject (TObject *o) {
luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
L->stack.stack[L->Cstack.base++] = *o;
return L->Cstack.base; /* this is +1 real position (see Ref) */
}
-static lua_Object put_luaObjectonTop (void)
-{
+static lua_Object put_luaObjectonTop (void) {
luaD_openstack((L->stack.top-L->stack.stack)-L->Cstack.base);
L->stack.stack[L->Cstack.base++] = *(--L->stack.top);
return L->Cstack.base; /* this is +1 real position (see Ref) */
}
-lua_Object lua_pop (void)
-{
+static void top2LC (int n) {
+ /* Put the 'n' elements on the top as the Lua2C contents */
+ L->Cstack.base = (L->stack.top-L->stack.stack); /* new base */
+ L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */
+ L->Cstack.num = n; /* number of results */
+}
+
+
+lua_Object lua_pop (void) {
checkCparams(1);
return put_luaObjectonTop();
}
@@ -436,6 +437,11 @@ TaggedString *luaA_nextvar (TaggedString *g) {
}
while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
g = (TaggedString *)g->head.next;
+ if (g) {
+ ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g;
+ incr_top;
+ luaA_pushobject(&g->u.s.globalval);
+ }
return g;
}
@@ -444,11 +450,37 @@ char *lua_nextvar (char *varname) {
TaggedString *g = (varname == NULL) ? NULL : luaS_new(varname);
g = luaA_nextvar(g);
if (g) {
- luaA_pushobject(&g->u.s.globalval);
+ top2LC(2);
return g->str;
}
- else
+ else {
+ top2LC(0);
return NULL;
+ }
+}
+
+
+int luaA_next (Hash *t, int i) {
+ Node *n;
+ int tsize = nhash(t);
+ while (i < tsize && ttype(val(n=node(t, i))) == LUA_T_NIL) i++;
+ if (i >= tsize)
+ return 0;
+ else {
+ luaA_pushobject(ref(n));
+ luaA_pushobject(val(n));
+ return i+1;
+ }
+}
+
+
+int lua_next (lua_Object o, int i) {
+ TObject *t = Address(o);
+ if (ttype(t) != LUA_T_ARRAY)
+ lua_error("API error: object is not a table in `lua_next'");
+ i = luaA_next(avalue(t), i);
+ top2LC((i==0) ? 0 : 2);
+ return i;
}
diff --git a/lapi.h b/lapi.h
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.h,v 1.2 1998/06/19 16:14:09 roberto Exp roberto $
+** $Id: lapi.h,v 1.3 1999/02/22 19:13:12 roberto Exp roberto $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
@@ -17,5 +17,6 @@ void luaA_pushobject (TObject *o);
void luaA_packresults (void);
int luaA_passresults (void);
TaggedString *luaA_nextvar (TaggedString *g);
+int luaA_next (Hash *t, int i);
#endif
diff --git a/lbuiltin.c b/lbuiltin.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbuiltin.c,v 1.52 1999/02/22 14:17:24 roberto Exp roberto $
+** $Id: lbuiltin.c,v 1.53 1999/02/22 19:13:12 roberto Exp roberto $
** Built-in functions
** See Copyright Notice in lua.h
*/
@@ -300,9 +300,76 @@ static void luaB_call (void) {
}
}
+
+static void luaB_nextvar (void) {
+ TObject *o = luaA_Address(luaL_nonnullarg(1));
+ TaggedString *g;
+ if (ttype(o) == LUA_T_NIL)
+ g = NULL;
+ else {
+ luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected");
+ g = tsvalue(o);
+ }
+ if (!luaA_nextvar(g))
+ lua_pushnil();
+}
+
+
+static void luaB_next (void) {
+ Hash *a = gethash(1);
+ TObject *k = luaA_Address(luaL_nonnullarg(2));
+ int i = (ttype(k) == LUA_T_NIL) ? 0 : luaH_pos(a, k)+1;
+ if (luaA_next(a, i) == 0)
+ lua_pushnil();
+}
+
+
+static void luaB_tostring (void) {
+ lua_Object obj = lua_getparam(1);
+ TObject *o = luaA_Address(obj);
+ char buff[64];
+ switch (ttype(o)) {
+ case LUA_T_NUMBER:
+ lua_pushstring(lua_getstring(obj));
+ return;
+ case LUA_T_STRING:
+ lua_pushobject(obj);
+ return;
+ case LUA_T_ARRAY:
+ sprintf(buff, "table: %p", (void *)o->value.a);
+ break;
+ case LUA_T_CLOSURE:
+ sprintf(buff, "function: %p", (void *)o->value.cl);
+ break;
+ case LUA_T_PROTO:
+ sprintf(buff, "function: %p", (void *)o->value.tf);
+ break;
+ case LUA_T_CPROTO:
+ sprintf(buff, "function: %p", (void *)o->value.f);
+ break;
+ case LUA_T_USERDATA:
+ sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
+ break;
+ case LUA_T_NIL:
+ lua_pushstring("nil");
+ return;
+ default:
+ LUA_INTERNALERROR("invalid type");
+ }
+ lua_pushstring(buff);
+}
+
+
+static void luaB_type (void) {
+ lua_Object o = luaL_nonnullarg(1);
+ lua_pushstring(luaO_typename(luaA_Address(o)));
+ lua_pushnumber(lua_tag(o));
+}
+
/* }====================================================== */
+
/*
** {======================================================
** "Extra" functions
@@ -352,7 +419,7 @@ static void luaB_foreach (void) {
luaD_calln(2, 1);
if (ttype(L->stack.top-1) != LUA_T_NIL)
return;
- L->stack.top--;
+ L->stack.top--; /* remove result */
}
}
}
@@ -361,22 +428,21 @@ static void luaB_foreach (void) {
static void luaB_foreachvar (void) {
TObject *f = luaA_Address(luaL_functionarg(1));
GCnode *g;
- StkId name = L->Cstack.base++; /* place to keep var name (to avoid GC) */
- luaD_checkstack(4); /* for var name, f, s, and globalvar */
- ttype(L->stack.stack+name) = LUA_T_NIL;
- L->stack.top++; /* top == base */
+ luaD_checkstack(4); /* for extra var name, f, var name, and globalval */
for (g = L->rootglobal.next; g; g = g->next) {
TaggedString *s = (TaggedString *)g;
if (s->u.s.globalval.ttype != LUA_T_NIL) {
- ttype(L->stack.stack+name) = LUA_T_STRING;
- tsvalue(L->stack.stack+name) = s; /* keep s on stack to avoid GC */
+ pushtagstring(s); /* keep (extra) s on stack to avoid GC */
*(L->stack.top++) = *f;
pushtagstring(s);
*(L->stack.top++) = s->u.s.globalval;
luaD_calln(2, 1);
- if (ttype(L->stack.top-1) != LUA_T_NIL)
+ if (ttype(L->stack.top-1) != LUA_T_NIL) {
+ L->stack.top--;
+ *(L->stack.top-1) = *L->stack.top; /* remove extra s */
return;
- L->stack.top--;
+ }
+ L->stack.top-=2; /* remove result and extra s */
}
}
}
@@ -505,85 +571,7 @@ static void luaB_sort (void) {
/*
-** {======================================================
-** Internal Functions.
-** These functions need access to internal structures
-** to be implemented.
-** =======================================================
-*/
-
-
-static void luaB_nextvar (void) {
- TObject *o = luaA_Address(luaL_nonnullarg(1));
- TaggedString *g;
- if (ttype(o) == LUA_T_NIL)
- g = NULL;
- else {
- luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected");
- g = tsvalue(o);
- }
- g = luaA_nextvar(g);
- if (g) {
- pushtagstring(g);
- luaA_pushobject(&g->u.s.globalval);
- }
- else lua_pushnil(); /* no more globals */
-}
-
-
-static void luaB_next (void) {
- Node *n = luaH_next(gethash(1), luaA_Address(luaL_nonnullarg(2)));
- if (n) {
- luaA_pushobject(&n->ref);
- luaA_pushobject(&n->val);
- }
- else lua_pushnil();
-}
-
-
-static void luaB_tostring (void) {
- lua_Object obj = lua_getparam(1);
- TObject *o = luaA_Address(obj);
- char buff[64];
- switch (ttype(o)) {
- case LUA_T_NUMBER:
- lua_pushstring(lua_getstring(obj));
- return;
- case LUA_T_STRING:
- lua_pushobject(obj);
- return;
- case LUA_T_ARRAY:
- sprintf(buff, "table: %p", (void *)o->value.a);
- break;
- case LUA_T_CLOSURE:
- sprintf(buff, "function: %p", (void *)o->value.cl);
- break;
- case LUA_T_PROTO:
- sprintf(buff, "function: %p", (void *)o->value.tf);
- break;
- case LUA_T_CPROTO:
- sprintf(buff, "function: %p", (void *)o->value.f);
- break;
- case LUA_T_USERDATA:
- sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
- break;
- case LUA_T_NIL:
- lua_pushstring("nil");
- return;
- default:
- LUA_INTERNALERROR("invalid type");
- }
- lua_pushstring(buff);
-}
-
-
-static void luaB_type (void) {
- lua_Object o = luaL_nonnullarg(1);
- lua_pushstring(luaO_typename(luaA_Address(o)));
- lua_pushnumber(lua_tag(o));
-}
-
-/* }====================================================== */
+** ====================================================== */
@@ -658,6 +646,12 @@ static void testC (void) {
case 'I': reg[getnum(s)] = lua_rawgettable(); break;
case 't': lua_settable(); break;
case 'T': lua_rawsettable(); break;
+ case 'N' : lua_pushstring(lua_nextvar(lua_getstring(reg[getnum(s)])));
+ break;
+ case 'n' : { int n=getnum(s);
+ n=lua_next(reg[n], lua_getnumber(reg[getnum(s)]));
+ lua_pushnumber(n); break;
+ }
default: luaL_verror("unknown command in `testC': %c", *(s-1));
}
if (*s == 0) return;
diff --git a/ltable.c b/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 1.19 1999/01/25 12:30:11 roberto Exp roberto $
+** $Id: ltable.c,v 1.20 1999/01/25 17:41:19 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -152,28 +152,10 @@ void luaH_set (Hash *t, TObject *ref, TObject *val) {
}
-static Node *hashnext (Hash *t, int i) {
- Node *n;
- int tsize = nhash(t);
- if (i >= tsize)
- return NULL;
- n = node(t, i);
- while (ttype(val(n)) == LUA_T_NIL) {
- if (++i >= tsize)
- return NULL;
- n = node(t, i);
- }
- return n;
-}
-
-Node *luaH_next (Hash *t, TObject *r) {
- if (ttype(r) == LUA_T_NIL)
- return hashnext(t, 0);
- else {
- Node *n = luaH_present(t, r);
- luaL_arg_check(ttype(val(n)) != LUA_T_NIL, 2, "key not found");
- return hashnext(t, (n-(t->node))+1);
- }
+int luaH_pos (Hash *t, TObject *r) {
+ Node *n = luaH_present(t, r);
+ luaL_arg_check(ttype(val(n)) != LUA_T_NIL, 2, "key not found");
+ return n-(t->node);
}
diff --git a/ltable.h b/ltable.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.h,v 1.9 1999/01/25 12:30:11 roberto Exp roberto $
+** $Id: ltable.h,v 1.10 1999/01/25 17:40:10 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -22,7 +22,7 @@ Hash *luaH_new (int nhash);
void luaH_free (Hash *frees);
Node *luaH_present (Hash *t, TObject *key);
void luaH_set (Hash *t, TObject *ref, TObject *val);
-Node *luaH_next (Hash *t, TObject *r);
+int luaH_pos (Hash *t, TObject *r);
void luaH_setint (Hash *t, int ref, TObject *val);
TObject *luaH_getint (Hash *t, int ref);
diff --git a/lua.h b/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.27 1999/02/09 15:59:22 roberto Exp roberto $
+** $Id: lua.h,v 1.28 1999/02/22 19:13:12 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
@@ -90,6 +90,8 @@ lua_Object lua_rawgettable (void); /* In: table, index */
int lua_tag (lua_Object object);
char *lua_nextvar (char *varname); /* Out: value */
+int lua_next (lua_Object o, int i);
+ /* Out: ref, value */
int lua_ref (int lock); /* In: value */
lua_Object lua_getref (int ref);