feat(lua): expose s-expressions in the Lua bindings
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
1e12ddc7a9
commit
f13a97397f
5 changed files with 131 additions and 1 deletions
|
@ -1 +1 @@
|
|||
add_library(lua util.cpp name.cpp numerics.cpp options.cpp)
|
||||
add_library(lua util.cpp name.cpp numerics.cpp options.cpp sexpr.cpp)
|
||||
|
|
105
src/bindings/lua/sexpr.cpp
Normal file
105
src/bindings/lua/sexpr.cpp
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#ifdef LEAN_USE_LUA
|
||||
#include <sstream>
|
||||
#include <lua.hpp>
|
||||
#include "util/debug.h"
|
||||
#include "util/sexpr/sexpr.h"
|
||||
#include "bindings/lua/util.h"
|
||||
#include "bindings/lua/name.h"
|
||||
#include "bindings/lua/numerics.h"
|
||||
|
||||
namespace lean {
|
||||
constexpr char const * sexpr_mt = "sexpr.mt";
|
||||
|
||||
static int push_sexpr(lua_State * L, sexpr const & e) {
|
||||
void * mem = lua_newuserdata(L, sizeof(sexpr));
|
||||
new (mem) sexpr(e);
|
||||
luaL_getmetatable(L, sexpr_mt);
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool is_sexpr(lua_State * L, int idx) {
|
||||
return testudata(L, idx, sexpr_mt);
|
||||
}
|
||||
|
||||
static sexpr to_sexpr(lua_State * L, int idx) {
|
||||
if (lua_isnil(L, idx)) {
|
||||
return sexpr();
|
||||
} else if (lua_isboolean(L, idx)) {
|
||||
return sexpr(lua_toboolean(L, idx));
|
||||
} else if (lua_isnumber(L, idx)) {
|
||||
// Remark: we convert to integer by default
|
||||
return sexpr(static_cast<int>(lua_tointeger(L, idx)));
|
||||
} else if (is_name(L, idx)) {
|
||||
return sexpr(to_name(L, idx));
|
||||
} else if (is_sexpr(L, idx)) {
|
||||
return *static_cast<sexpr*>(lua_touserdata(L, idx));
|
||||
} else if (is_mpz(L, idx)) {
|
||||
return sexpr(to_mpz(L, idx));
|
||||
} else if (is_mpq(L, idx)) {
|
||||
return sexpr(to_mpq(L, idx));
|
||||
} else {
|
||||
return sexpr(lua_tostring(L, idx));
|
||||
}
|
||||
}
|
||||
|
||||
static int sexpr_gc(lua_State * L) {
|
||||
to_sexpr(L, 1).~sexpr();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sexpr_tostring(lua_State * L) {
|
||||
std::ostringstream out;
|
||||
out << to_sexpr(L, 1);
|
||||
lua_pushfstring(L, out.str().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mk_sexpr(lua_State * L) {
|
||||
sexpr r;
|
||||
int nargs = lua_gettop(L);
|
||||
if (nargs == 0) {
|
||||
r = sexpr();
|
||||
} else {
|
||||
int i = nargs;
|
||||
r = to_sexpr(L, i);
|
||||
i--;
|
||||
for (; i >= 1; i--) {
|
||||
r = sexpr(to_sexpr(L, i), r);
|
||||
}
|
||||
}
|
||||
return push_sexpr(L, r);
|
||||
}
|
||||
|
||||
static int sexpr_eq(lua_State * L) {
|
||||
lua_pushboolean(L, to_sexpr(L, 1) == to_sexpr(L, 2));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int sexpr_lt(lua_State * L) {
|
||||
lua_pushboolean(L, to_sexpr(L, 1) < to_sexpr(L, 2));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg sexpr_m[] = {
|
||||
{"__gc", sexpr_gc}, // never throws
|
||||
{"__tostring", safe_function<sexpr_tostring>},
|
||||
{"__eq", safe_function<sexpr_eq>},
|
||||
{"__lt", safe_function<sexpr_lt>},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
void open_sexpr(lua_State * L) {
|
||||
luaL_newmetatable(L, sexpr_mt);
|
||||
setfuncs(L, sexpr_m, 0);
|
||||
lua_pushcfunction(L, safe_function<mk_sexpr>);
|
||||
lua_setglobal(L, "sexpr");
|
||||
}
|
||||
}
|
||||
#endif
|
15
src/bindings/lua/sexpr.h
Normal file
15
src/bindings/lua/sexpr.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#ifdef LEAN_USE_LUA
|
||||
#include <lua.hpp>
|
||||
namespace lean {
|
||||
class sexpr;
|
||||
void open_sexpr(lua_State * L);
|
||||
bool is_sexpr(lua_State * L, int idx);
|
||||
sexpr to_sexpr(lua_State * L, int idx);
|
||||
}
|
||||
#endif
|
|
@ -12,6 +12,7 @@ Author: Leonardo de Moura
|
|||
#include "bindings/lua/name.h"
|
||||
#include "bindings/lua/numerics.h"
|
||||
#include "bindings/lua/options.h"
|
||||
#include "bindings/lua/sexpr.h"
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
int status, result;
|
||||
|
@ -23,6 +24,7 @@ int main(int argc, char ** argv) {
|
|||
lean::open_mpz(L);
|
||||
lean::open_mpq(L);
|
||||
lean::open_options(L);
|
||||
lean::open_sexpr(L);
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
status = luaL_loadfile(L, argv[i]);
|
||||
|
|
8
tests/lua/sexpr1.lua
Normal file
8
tests/lua/sexpr1.lua
Normal file
|
@ -0,0 +1,8 @@
|
|||
s = sexpr(1, 2, 3)
|
||||
print(s)
|
||||
s = sexpr(1, 2, 3, nil)
|
||||
print(s)
|
||||
s = sexpr(sexpr(1, 2), sexpr(3, 4), nil)
|
||||
print(s)
|
||||
s = sexpr(mpz("100000000000000"), mpq(3)/2, sexpr(1, 2, 3, nil), nil)
|
||||
print(s)
|
Loading…
Reference in a new issue