From 8b5f6266dabcf384b330a5b25ee22b7daa7bc574 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Sun, 10 Aug 2008 16:14:16 +0200 Subject: [PATCH] lua: add support for __pairs and __next metamethods Signed-off-by: Julien Danjou --- lua.c | 39 +++++++++++++++++++++++++++++++++++++++ lua.h | 11 ++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/lua.c b/lua.c index 485e7f9e..13c0144d 100644 --- a/lua.c +++ b/lua.c @@ -427,6 +427,38 @@ luaA_mbstrlen(lua_State *L) return 1; } +static int +luaA_next(lua_State *L) +{ + if(luaL_getmetafield(L, 1, "__next")) + { + lua_insert(L, 1); + lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); + return lua_gettop(L); + } + + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); + if(lua_next(L, 1)) + return 2; + lua_pushnil(L); + return 1; +} + +static int +luaA_pairs(lua_State *L) +{ + if(luaL_getmetafield(L, 1, "__pairs")) + { + lua_insert(L, 1); + lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); + return lua_gettop(L); + } + + luaL_checktype(L, 1, LUA_TTABLE); + return luaA_generic_pairs(L); +} + static void luaA_fixups(lua_State *L) { @@ -434,6 +466,13 @@ luaA_fixups(lua_State *L) lua_pushcfunction(L, luaA_mbstrlen); lua_setfield(L, -2, "len"); lua_pop(L, 1); + lua_pushliteral(L, "next"); + lua_pushcfunction(L, luaA_next); + lua_settable(L, LUA_GLOBALSINDEX); + lua_pushliteral(L, "pairs"); + lua_pushcfunction(L, luaA_next); + lua_pushcclosure(L, luaA_pairs, 1); /* pairs get next as upvalue */ + lua_settable(L, LUA_GLOBALSINDEX); } /** Object table. diff --git a/lua.h b/lua.h index a70be2b2..0fa0fb9e 100644 --- a/lua.h +++ b/lua.h @@ -248,7 +248,16 @@ void luaA_pushpointer(lua_State *, void *, awesome_type_t); void luaA_cs_init(void); void luaA_cs_cleanup(void); void luaA_on_timer(EV_P_ ev_timer *w, int revents); -void luaA_pushcolor(lua_State *, const xcolor_t *c); +void luaA_pushcolor(lua_State *, const xcolor_t *); + +static inline int +luaA_generic_pairs(lua_State *L) +{ + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushnil(L); /* and initial value */ + return 3; +} #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80