Я пытаюсь переместить стол на другой стол, используя lua C api. Например, у меня есть таблица с этой структурой:
a[b][c][d][e] = value
Я хочу переместить таблицу d, чтобы она была под a [b], что я мог бы сделать в Lua следующим образом:
a[b][d] = a[b][c][d]
a[b][c][d] = nil
Мой текущий подход заключается в загрузке в стек таблицы a [b] [c] [d], поэтому стек выглядит следующим образом:
Index Value
-1 d table
-2 c table
-3 b table
-4 a table
Затем загрузите a [b] в стек, чтобы он выглядел следующим образом:
Index Value
-1 b table
-2 a table
-3 d table
-4 c table
-5 b table
-6 a table
Затем поместите ключ d в стек и вставьте ключ d и таблицу b под таблицей d, чтобы стек был:
Index Value
-1 d table
-2 d key
-3 b table
-4 a table
-5 c table
-6 b table
-7 a table
Затем я использую lua_settable (L, -3), чтобы сделать b [d] = d.
Этот подход работает для ключей вне таблиц, но не работает для ключей, которые являются таблицами. Так что это не удастся для чего-то вроде:
a[b][c][{}][d] = value
a[b] = a[b][c][{}][d]
Обратите внимание, я знаю, что в приведенном выше примере произойдет сбой в lua, указанном выше, поскольку ключом будет новая таблица lua, я просто хотел это проиллюстрировать.
Я попытался спуститься по столу родителей (так что a [b] = b, lua_setglobal (L, a)) тоже безуспешно. Кто-нибудь знает, где я здесь не так?
Редактировать:
Небольшой фрагмент кода о том, как я помещаю ключи / значения в стек. Цель здесь — переместить таблицу из одной структуры таблицы в другую (или, как я ее называю в коде, переписать ее)
Решение:
Проблема заключалась в том, что в таблице была какая-то метатабельная функция, которая предотвращала изменения в таблице (по сути, у человека, создавшего сценарий, была таблица конфигурации, где структура была важна, что и вызвало эту проблему.)
Если я правильно понимаю ваше описание, этот код Lua делает то, что вы хотите:
local ab = a[b]
ab[d], ab[c][d] = ab[c][d], nil
Что касается реализации этого в Lua C API, lua2c полезно с этим машинным переводом:
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;
Мне еще предстоит разработать читабельный способ написания стековых операций.
Других решений пока нет …