/* Copyright (c) 2013 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Author: Leonardo de Moura */ #include #include #include "kernel/context.h" #include "bindings/lua/util.h" #include "bindings/lua/name.h" #include "bindings/lua/expr.h" #include "bindings/lua/context.h" namespace lean { constexpr char const * context_entry_mt = "context_entry.mt"; bool is_context_entry(lua_State * L, int idx) { return testudata(L, idx, context_entry_mt); } context_entry & to_context_entry(lua_State * L, int idx) { return *static_cast(luaL_checkudata(L, idx, context_entry_mt)); } int push_context_entry(lua_State * L, context_entry const & e) { void * mem = lua_newuserdata(L, sizeof(context_entry)); new (mem) context_entry(e); luaL_getmetatable(L, context_entry_mt); lua_setmetatable(L, -2); return 1; } static int context_entry_gc(lua_State * L) { to_context_entry(L, 1).~context_entry(); return 0; } static int mk_context_entry(lua_State * L) { int nargs = lua_gettop(L); if (nargs == 2) return push_context_entry(L, context_entry(to_name_ext(L, 1), to_expr(L, 2))); else return push_context_entry(L, context_entry(to_name_ext(L, 1), to_expr(L, 2), to_expr(L, 3))); } static int context_entry_pred(lua_State * L) { lua_pushboolean(L, is_context_entry(L, 1)); return 1; } static int context_entry_get_name(lua_State * L) { return push_name(L, to_context_entry(L, 1).get_name()); } static int context_entry_get_domain(lua_State * L) { return push_expr(L, to_context_entry(L, 1).get_domain()); } static int context_entry_get_body(lua_State * L) { return push_expr(L, to_context_entry(L, 1).get_body()); } static const struct luaL_Reg context_entry_m[] = { {"__gc", context_entry_gc}, // never throws {"get_name", safe_function}, {"get_domain", safe_function}, {"get_body", safe_function}, {0, 0} }; constexpr char const * context_mt = "context.mt"; bool is_context(lua_State * L, int idx) { return testudata(L, idx, context_mt); } context & to_context(lua_State * L, int idx) { return *static_cast(luaL_checkudata(L, idx, context_mt)); } int push_context(lua_State * L, context const & e) { void * mem = lua_newuserdata(L, sizeof(context)); new (mem) context(e); luaL_getmetatable(L, context_mt); lua_setmetatable(L, -2); return 1; } static int context_gc(lua_State * L) { to_context(L, 1).~context(); return 0; } static int context_tostring(lua_State * L) { std::ostringstream out; // TODO(Leo): use pretty printer out << to_context(L, 1); lua_pushfstring(L, out.str().c_str()); return 1; } static int mk_context(lua_State * L) { int nargs = lua_gettop(L); if (nargs == 0) { return push_context(L, context()); } else if (nargs == 2) { context_entry & e = to_context_entry(L, 2); return push_context(L, context(to_context(L, 1), e.get_name(), e.get_domain(), e.get_body())); } else if (nargs == 3) { return push_context(L, context(to_context(L, 1), to_name_ext(L, 2), to_expr(L, 3))); } else { return push_context(L, context(to_context(L, 1), to_name_ext(L, 2), to_expr(L, 3), to_expr(L, 4))); } } static int context_pred(lua_State * L) { lua_pushboolean(L, is_context(L, 1)); return 1; } static int context_extend(lua_State * L) { int nargs = lua_gettop(L); if (nargs != 3 && nargs != 4) luaL_error(L, "extend expect 3 or 4 arguments"); return mk_context(L); } static int context_is_empty(lua_State * L) { lua_pushboolean(L, empty(to_context(L, 1))); return 1; } static int context_lookup(lua_State * L) { auto p = lookup_ext(to_context(L, 1), luaL_checkinteger(L, 2)); push_context_entry(L, p.first); push_context(L, p.second); return 2; } static int context_size(lua_State * L) { lua_pushinteger(L, to_context(L, 1).size()); return 1; } static const struct luaL_Reg context_m[] = { {"__gc", context_gc}, // never throws {"__tostring", safe_function}, {"__len", safe_function}, {"is_empty", safe_function}, {"size", safe_function}, {0, 0} }; void open_context(lua_State * L) { luaL_newmetatable(L, context_entry_mt); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); setfuncs(L, context_entry_m, 0); set_global_function(L, "context_entry"); set_global_function(L, "is_context_entry"); luaL_newmetatable(L, context_mt); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); setfuncs(L, context_m, 0); set_global_function(L, "context"); set_global_function(L, "is_context"); set_global_function(L, "extend"); set_global_function(L, "lookup"); } }