Removing all items from Lua table in C

Viewed 402

Is it possible to quickly remove all items from a Lua table in C without manually removing all items individually?

I know, I can do that in Lua by simply saying

t = {}

but I'm specifically looking for a solution in C that removes all items from a table that is somewhere on the stack.

1 Answers

It is often inappropriate to change something idiomatic of a language, for the sake of those unfamiliar.

If you want to make a clear that does the same as t={} you can use lua_replace.

emptying a table and t={} are not the same thing.

to illustrate:

local tab1 = {1,2,3,4,5}

local tab2 = tab1

function clear(t)
    for k in pairs(t) do
        t[k] = nil
    end
end

clear(tab2)

for k, v in pairs(tab1) do
    print(k, v)
end

This results in no values in tab1. This is because tab1 and tab2 reference the same table so changes made to tab2 are reflected in tab1.

local tab1 = {1,2,3,4,5}

local tab2 = tab1

tab2 = {}

for k, v in pairs(tab1) do
    print(k, v)
end

Here we get

1 1

2 2

3 3

4 4

5 5

this is because tab2 was pointed to another table and did not alter the table it was previously referenced to.

If you wanted to do the first example in the c api you could do it like this:

/* name: clear
 * function(t) */
static int lcf1_clear (lua_State * L) {
  enum { lc_nformalargs = 1 };
  lua_settop(L,1);
  
  /* for k in pairs(t) do
   * internal: local f, s, var = explist */
  enum { lc1 = 1 };
  lua_getfield(L,LUA_ENVIRONINDEX,"pairs");
  lua_pushvalue(L,1);
  lua_call(L,1,3);
  while (1) {
    
    /* internal: local var_1, ..., var_n = f(s, var)
     *           if var_1 == nil then break end
     *           var = var_1 */
    lua_pushvalue(L,-3);
    lua_pushvalue(L,-3);
    lua_pushvalue(L,-3);
    lua_call(L,2,1);
    if (lua_isnil(L,-1)) {
      break;
    }
    lua_pushvalue(L,-1);
    lua_replace(L,-3);
    
    /* internal: local k with idx 5 */
    
    
    /* t[k] = nil */
    lua_pushnil(L);
    lua_pushvalue(L,5);
    lua_insert(L,-2);
    lua_settable(L,1);
    assert(lua_gettop(L) == 5);
    
    /* internal: stack cleanup on scope exit */
    lua_pop(L,1);
  }
  lua_settop(L,lc1);
  assert(lua_gettop(L) == 1);
  return 0;
}

This was generated using lua2c for lua 5.1, it is something that could use some improvement but to get the general idea of how to do something in the c api it works, and it can be a helpful tool for getting some understanding.

that all said again I strongly suggest you dont change something idiomatic like this.

Related