From f04c83e0759b1059545ea0526c5999c35cb1793f Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 23 Feb 1999 11:57:28 -0300 Subject: new function "lua_next" (+ new implementation for "next") --- lbuiltin.c | 172 +++++++++++++++++++++++++++++-------------------------------- 1 file changed, 83 insertions(+), 89 deletions(-) (limited to 'lbuiltin.c') diff --git a/lbuiltin.c b/lbuiltin.c index 1143dae7..9971f5a1 100644 --- 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; -- cgit v1.2.3-55-g6feb