lua-users home
lua-l archive

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


It was thus said that the Great Philipp Kraus once stated:
> Hello,
> 
> I generate a table with
> 
> lua_newtable
> lua_pushxxx()
> lua_setfield(L, -2, "mykey")
> lua_setglobal
> 
> 
> This works at the moment, I try to create a table like
> {   "key1" : { "subkey" : 123 }, "key2" : { "subkey" : 456 } }
> 
> but I don't know how to append some new elements like
> {   "key1" : { "subkey" : 123 }, "key2" : { "subkey" : 456, "newkey" : 789} }
> 
> I get the first table put it on top of the stack, than I use getfield to
> check if the field exists, if it is nil, I pop the nil value and run newtable,
> but if the value with the key exists (it must be a table), than the table is on top,
> but how can I add on a table a new key-value pair? So I would like to
> overwrite an existing key or I would like to append a new one.
> Must I put all element on the stack top? 
> 
> in short I try to solve this:
> 
> if table exists
>      push it on the stack
>      if key exists
>         push it on the stack and replace value
>      else
>         push a new key-value pair on the stack
>         add it to table
>     move table from stack and append data
> else
>      create table
>      create key-value pair and put it into table
> 
> Can me anybody explain how the append works?

  Assuming the following:

t = { key1 = { subkey = 123 } , key2 = { subkey = 456 , newkey = 789 } }
my_append(t)

Then:

int my_append(lua_State *L)
{
  luaL_checktype(L,1,LUA_TTABLE);	/* t -- t      */ /* make sure we only have a table */
  lua_getfield(L,-1,"key2");		/* t -- t key2 */ /* get key2 */
  if (lua_isnil(L,-1))
  {
    lua_pop(L,1);			/* t nil -- t     */ /* pop nil from stack */
    lua_createtable(L,0,0);		/* t     -- t t   */ /* create a table */
    lua_pushvalue(L,-1);		/* t t   -- t t t */ /* dup it */
    lua_setfield(L,-3,"key2");		/* t t t -- t t   */ /* and set it as key2 in the passed in table */
  }
  else
    luaL_checktype(L,-1,LUA_TTABLE);	/* t t -- t t */ /* make sure it's a table */

  lua_pushinteger(L,314);		/* t t     -- t t 314 */ /* set anewkey to 314 */
  lua_setfield(L,-2,"anewerkey");       /* t t 314 -- t t     */

  lua_pop(L,1);				/* t t -- t */
  return 1;				/* return passed in table */
}

Untested code, but the above should set key2.anewerkey to 314 in the passed
in table (and create key2 if it doesn't exist).  The first comments is a
stack diagram (a concept from Forth)---the top of the stack is always on the
right, and the diagram shows the stack before and after the function
(stack-before-call '--' stack-after-call), which should make the logic a bit
more clearer.

  -spc