lua-users home
lua-l archive

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


Following the recent discussion about table.concat, here is some code that
supports the use of tables as ropes. It provides a single function "unrope"
which takes a rope (a table containing strings and similar subtables) and
concats it into a single string, optionally with delimiters.
Enjoy. All feedback welcome.
--lhf
/*
* lrope.c
* provides unrope
* Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br>
* 04 Dec 2008 10:08:49
* This code is hereby placed in the public domain.
*/

#include "lua.h"
#include "lauxlib.h"

#define MAXLEVEL 30

static int doconcat (lua_State *L, luaL_Buffer *b, int t, int needsep) {
  int i;
  if (t>MAXLEVEL+1) luaL_error(L, "table too deep for "LUA_QL("unrope"));
  for (i=1;; i++)
  {
    lua_rawgeti(L,t,i);
    switch (lua_type(L,-1))
    {
      case LUA_TNIL:
	return needsep;
      case LUA_TNUMBER:
      case LUA_TSTRING:
        if (needsep) {lua_pushvalue(L,1); luaL_addvalue(b);}
        luaL_addvalue(b);
        needsep=1;
        break;
      case LUA_TTABLE:
        lua_replace(L,t+1);
        needsep=doconcat(L,b,t+1,needsep);
        break;
    }
 }
}

static int unrope (lua_State *L) {
  luaL_Buffer b;
  luaL_checktype(L, 1, LUA_TTABLE);
  if (lua_isnoneornil(L,2)) lua_pushliteral(L,"");
  lua_settop(L,2);
  lua_insert(L,1);
  luaL_checkstack(L,MAXLEVEL-1,"cannot grow stack");
  lua_settop(L,MAXLEVEL+1);
  luaL_buffinit(L,&b);
  doconcat(L,&b,2,0);
  luaL_pushresult(&b);
  return 1;
}

LUALIB_API int luaopen_rope (lua_State *L) {
  lua_register(L, "unrope", unrope);
  return 0;
}
require"rope"

function test(t)
	print("","["..unrope(t,"/").."]")
end

function try(t)
	print(t)
	assert(loadstring(t,"="..t))()
end

try"test{1,2,{3,4,{5,6},7},8,9}"
try"test{}"
try"test{1}"
try"test{1,2}"
try"test{1,2,3}"
try"test{1,2,{}}"
try"test{{}}"
try"test{{},{}}"
try"test{{1},{}}"
try"test{{},{2}}"
try"test{{1},{},3}"
try"test{{1}}"
try"test{{1},false,3}"

--do return end

try[[test{ "jan", "fev", { "mar", "abr" }, "mai", { }, "jun", { "jul" }, "ago",
{ "sep", { "oct", "nov" }},
{{{{{{{{{{{{{{{{{{{{{"dec"}}}}}}}}}}}}}}}}}}}}},
}]]

print"bye"
test{1,2,{3,4,{5,6},7},8,9}
	[1/2/3/4/5/6/7/8/9]
test{}
	[]
test{1}
	[1]
test{1,2}
	[1/2]
test{1,2,3}
	[1/2/3]
test{1,2,{}}
	[1/2]
test{{}}
	[]
test{{},{}}
	[]
test{{1},{}}
	[1]
test{{},{2}}
	[2]
test{{1},{},3}
	[1/3]
test{{1}}
	[1]
test{{1},false,3}
	[1/3]
test{ "jan", "fev", { "mar", "abr" }, "mai", { }, "jun", { "jul" }, "ago",
{ "sep", { "oct", "nov" }},
{{{{{{{{{{{{{{{{{{{{{"dec"}}}}}}}}}}}}}}}}}}}}},
}
	[jan/fev/mar/abr/mai/jun/jul/ago/sep/oct/nov/dec]
bye