简体   繁体   中英

How to do lua table operations from C?

I need to perform operations on Lua tables from C where the tables are treated as lists or queues. Specifically I need to insert an element at the head, and remove the head element, and have the other elements move to accommodate the new element.

This would be simple in straight lua, I'd use table.insert and table.remove . But in C ?

There are functions in the Lua C api such as lua_settable, but no equivalents for table.insert and table.remove that are surfaced. It looks like there are internal C functions inside the interpreter called tinsert and tremove , but they are not part of the api.

Do I really have to call out to a lua function that does it for me?

I believe you can reuse the functions

static int tinsert (lua_State *L)
static int tremove (lua_State *L)

and the macro

#define aux_getn(L,n)   (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))

which are in the ltablib.c. They depend only on Lua's API.

Code not tested, but here's a sketch. You pass the index of the table, and for the insert function, also the index of the value you want to insert. For removal, the value gets pushed on the Lua stack.

#define getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))

void insert_at_head (lua_State *L, int tbl_idx, int val_idx) {
  int e;
  /* shift elements right to make room */
  for (e = getn(L, tbl_idx) + 1; e > 1; e--) {
    lua_rawgeti(L, tbl_idx, e-1);
    lua_rawseti(L, tbl_idx, e);
  }
  lua_pushvalue(L, val_idx);
  lua_rawseti(L, tbl_idx, 1);
}

void remove_from_head_and_push (lua_State *L, int tbl_idx) {
  int e;
  int n = getn(L, tbl_idx);
  if (n == 0)
    return luaL_error("removed from head of empty list");
  lua_rawgeti(L, tbl_idx, 1);  /* push first element */
  /* shift elements left */
  for (e = 2; e < n; e++)
    lua_rawgeti(L, tbl_idx, e);
    lua_rawseti(L, tbl_idx, e-1);
  }
  lua_pushnil(L, val_idx);
  lua_rawseti(L, tbl_idx, n);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM