refactor(lua/name): improve name bindings for Lua

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-11-04 18:43:41 -08:00
parent f488e6bbfc
commit 7b77863507
2 changed files with 22 additions and 36 deletions

View file

@ -24,63 +24,48 @@ static const struct luaL_Reg name_m[] = {
{0, 0} {0, 0}
}; };
static name const & to_name(lua_State * L, unsigned idx) {
return *static_cast<name*>(luaL_checkudata(L, idx, "name.mt"));
}
static int mk_name(lua_State * L) { static int mk_name(lua_State * L) {
int nargs = lua_gettop(L); int nargs = lua_gettop(L);
if (nargs != 1 && nargs != 2) name r;
return luaL_error(L, "function 'name' expects 1 or 2 arguments"); for (int i = 1; i <= nargs; i++) {
if (nargs == 1) { if (lua_isnil(L, i)) {
char const * str = luaL_checkstring(L, 1); // skip
void * mem = lua_newuserdata(L, sizeof(name)); } else if (lua_isuserdata(L, i)) {
new (mem) name(str); r = r + to_name(L, i);
} else { } else if (lua_isstring(L, i)) {
lean_assert(nargs == 2); r = name(r, luaL_checkstring(L, i));
name tmp;
name * prefix;
if (lua_isstring(L, 1)) {
char const * str = luaL_checkstring(L, 1);
tmp = name(str);
prefix = &tmp;
} else { } else {
prefix = static_cast<name*>(luaL_checkudata(L, 1, "name.mt")); r = name(r, luaL_checkinteger(L, i));
}
if (lua_isstring(L, 2)) {
char const * str = luaL_checkstring(L, 2);
void * mem = lua_newuserdata(L, sizeof(name));
new (mem) name(*prefix, str);
} else {
int idx = luaL_checkinteger(L, 2);
void * mem = lua_newuserdata(L, sizeof(name));
new (mem) name(*prefix, idx);
} }
} }
void * mem = lua_newuserdata(L, sizeof(name));
new (mem) name(r);
luaL_getmetatable(L, "name.mt"); luaL_getmetatable(L, "name.mt");
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
return 1; return 1;
} }
static int name_gc(lua_State * L) { static int name_gc(lua_State * L) {
name * n = static_cast<name*>(luaL_checkudata(L, 1, "name.mt")); to_name(L, 1).~name();
n->~name();
return 0; return 0;
} }
static int name_tostring(lua_State * L) { static int name_tostring(lua_State * L) {
name * n = static_cast<name*>(luaL_checkudata(L, 1, "name.mt")); lua_pushfstring(L, to_name(L, 1).to_string().c_str());
lua_pushfstring(L, n->to_string().c_str());
return 1; return 1;
} }
static int name_eq(lua_State * L) { static int name_eq(lua_State * L) {
name * n1 = static_cast<name*>(luaL_checkudata(L, 1, "name.mt")); lua_pushboolean(L, to_name(L, 1) == to_name(L, 2));
name * n2 = static_cast<name*>(luaL_checkudata(L, 2, "name.mt"));
lua_pushboolean(L, *n1 == *n2);
return 1; return 1;
} }
static int name_lt(lua_State * L) { static int name_lt(lua_State * L) {
name * n1 = static_cast<name*>(luaL_checkudata(L, 1, "name.mt")); lua_pushboolean(L, to_name(L, 1) < to_name(L, 2));
name * n2 = static_cast<name*>(luaL_checkudata(L, 2, "name.mt"));
lua_pushboolean(L, *n1 < *n2);
return 1; return 1;
} }

View file

@ -1,7 +1,8 @@
n = name("foo", 1) n = name("foo", 1, 2)
print(n) print(n)
print(name(n, "bla")) print(name(n, "bla"))
print(n == name("foo", 1)) print(n == name("foo", 1))
print(n == name("foo", 2)) print(n == name("foo", 2))
print(n < name("foo", 2)) print(n < name("foo", 2))
print(n < name("foo", 0)) print(n < name("foo", 0))
print(name(nil))