lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


One way of implementing it, which is used to get the C equivalent of
"for k, v in pairs(t) do ... end": (MIT license, if anyone cares)
int luaL_pairs(lua_State *L, int index) {
  /* Start of iteration? */
  if (lua_isnil(L, -1)) {
    lua_checkstack(L, 2);
    if (luaL_getmetafield(L, index, "__pairs")) {
      lua_pushvalue(L, index);
      lua_replace(L, -4);
      lua_replace(L, -4);
      lua_pop(L, 1);
      lua_call(L, 1, 3);
      if(lua_isnil(L, -3)) {
        lua_pop(L, 2);
        lua_call(L, 0, 0);
      }
    }
  }
  /* Continuation of iteration */
  if(lua_isnil(L, -3)) {
    if (lua_next(L, index))
      return 1;
    lua_pop(L, 2);
    return 0;
  }
  else {
    lua_pushvalue(L, -3);
    lua_pushvalue(L, -3);
    lua_pushvalue(L, -3);
    lua_remove(L, -4);
    lua_call(L, 2, 2);
    if (lua_isnil(L, -2)) {
      lua_pop(L, 4);
      return 0;
    }
    return 1;
  }
}

Usage is then similar to, but not quite the same as, lua_next:
/* table is in the stack at index 't' */
lua_settop(L, lua_gettop(L) + 3); /* state variables and first key */
while (luaL_pairs(L, t) != 0) {
  /* uses 'key' (at index -2) and 'value' (at index -1) */
  printf("%s - %s\n",
         lua_typename(L, lua_type(L, -2)),
         lua_typename(L, lua_type(L, -1)));
  /* removes 'value'; keeps 'key' for next iteration */
  lua_pop(L, 1);
}

On Thu, Jan 14, 2010 at 11:20 PM, David Burgess <dabsoft@gmail.com> wrote:
> OK then. How about luaL_pairs()?
>
> On 15/1/2010 9:50 AM, Luiz Henrique de Figueiredo wrote:
>>>
>>> I think we should have lua_pairs() to match lua_next()
>>
>> __pairs is not a core metamethod, just like __tostring: it is provided
>> by the base library. So, it cannot influence the C API.
>