سؤال

I'm attempting to move a table to another table using the lua C api. For instance, I have a table with this structure:

a[b][c][d][e] = value

I want to move table d this to be under a[b], which I could accomplish in Lua like:

a[b][d] = a[b][c][d]
a[b][c][d] = nil

My current approach is to load on the stack the a[b][c][d] table, so the stack looks like:

Index  Value
-1     d table
-2     c table
-3     b table
-4     a table

Then load a[b] onto the stack, so it looks like:

Index  Value
-1     b table
-2     a table
-3     d table
-4     c table
-5     b table
-6     a table

Then put d's key onto the stack, and insert d's key and table b under table d, so the stack is:

Index  Value
-1     d table
-2     d key
-3     b table
-4     a table
-5     c table
-6     b table
-7     a table

Then I use lua_settable(L, -3), to do b[d] = d.

This approach works for non-table keys, but fails for keys which are tables. So it will fail for something like:

a[b][c][{}][d] = value
a[b] = a[b][c][{}][d]

Note, I know in the above it will fail in the lua given above because the key would be a new lua table, I just wanted to illustrate it.

I've tried going down the table parents (so doing a[b] = b, lua_setglobal(L, a)) without any luck either. Does anyone know where I'm going wrong here?

Edit: A small code snippet on how I push keys/values onto the stack. The goal here is to move a table from one table structure to another (or as I call it in the code, reparent it)

http://pastebin.com/Y4540Wss

Solution:

The issue was the table has some metatable function which prevented changes to the table (in essence, the person making the script had a config table where the structure was important, thus causing this issue.)

هل كانت مفيدة؟

المحلول

If I understand your description correctly, this Lua code does what you want:

local ab = a[b]
ab[d], ab[c][d] = ab[c][d], nil

As for implementing that in the Lua C API, lua2c is helpful with this machine translation:

enum { lc_nformalargs = 0 };
const int lc_nactualargs = lua_gettop(L);
const int lc_nextra = (lc_nactualargs - lc_nformalargs);

/* local ab = a[b] */
lua_getfield(L,LUA_ENVIRONINDEX,"a");
lua_getfield(L,LUA_ENVIRONINDEX,"b");
lua_gettable(L,-2);
lua_remove(L,-2);
assert(lua_gettop(L) - lc_nextra == 1);

/* ab[d], ab[c][d] = ab[c][d], nil */
lua_getfield(L,LUA_ENVIRONINDEX,"c");
lua_gettable(L,(1 + lc_nextra));
lua_getfield(L,LUA_ENVIRONINDEX,"d");
lua_gettable(L,-2);
lua_remove(L,-2);
lua_pushnil(L);
lua_getfield(L,LUA_ENVIRONINDEX,"c");
lua_gettable(L,(1 + lc_nextra));
lua_insert(L,-2);
lua_getfield(L,LUA_ENVIRONINDEX,"d");
lua_insert(L,-2);
lua_settable(L,-3);
lua_pop(L,1);
lua_getfield(L,LUA_ENVIRONINDEX,"d");
lua_insert(L,-2);
lua_settable(L,(1 + lc_nextra));
assert(lua_gettop(L) - lc_nextra == 1);
return 0;

I have yet to develop a readable way of writing stack operations.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top