feat(library/coercion): expose coercion module in the Lua API
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
2be9bcef78
commit
6536232107
5 changed files with 77 additions and 13 deletions
|
@ -12,6 +12,7 @@ Author: Leonardo de Moura
|
||||||
#include "library/coercion.h"
|
#include "library/coercion.h"
|
||||||
#include "library/module.h"
|
#include "library/module.h"
|
||||||
#include "library/kernel_serializer.h"
|
#include "library/kernel_serializer.h"
|
||||||
|
#include "library/kernel_bindings.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
enum class coercion_class_kind { User, Sort, Fun };
|
enum class coercion_class_kind { User, Sort, Fun };
|
||||||
|
@ -408,4 +409,59 @@ bool get_user_coercions(environment const & env, expr const & C, buffer<std::pai
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int add_coercion(lua_State * L) {
|
||||||
|
int nargs = lua_gettop(L);
|
||||||
|
if (nargs == 2)
|
||||||
|
return push_environment(L, add_coercion(to_environment(L, 1), to_name_ext(L, 2), get_io_state(L)));
|
||||||
|
else if (nargs == 3 && is_io_state(L, 3))
|
||||||
|
return push_environment(L, add_coercion(to_environment(L, 1), to_name_ext(L, 2), to_io_state(L, 3)));
|
||||||
|
else if (nargs == 3)
|
||||||
|
return push_environment(L, add_coercion(to_environment(L, 1), to_name_ext(L, 2), to_name_ext(L, 3), get_io_state(L)));
|
||||||
|
else
|
||||||
|
return push_environment(L, add_coercion(to_environment(L, 1), to_name_ext(L, 2), to_name_ext(L, 3), to_io_state(L, 4)));
|
||||||
|
}
|
||||||
|
static int is_coercion(lua_State * L) { return push_boolean(L, is_coercion(to_environment(L, 1), to_expr(L, 2))); }
|
||||||
|
static int has_coercions_from(lua_State * L) {
|
||||||
|
if (is_expr(L, 2))
|
||||||
|
return push_boolean(L, has_coercions_from(to_environment(L, 1), to_expr(L, 2)));
|
||||||
|
else
|
||||||
|
return push_boolean(L, has_coercions_from(to_environment(L, 1), to_name_ext(L, 2)));
|
||||||
|
}
|
||||||
|
static int has_coercions_to(lua_State * L) {
|
||||||
|
if (is_expr(L, 2))
|
||||||
|
return push_boolean(L, has_coercions_to(to_environment(L, 1), to_expr(L, 2)));
|
||||||
|
else
|
||||||
|
return push_boolean(L, has_coercions_to(to_environment(L, 1), to_name_ext(L, 2)));
|
||||||
|
}
|
||||||
|
static int get_coercion(lua_State * L) { return push_optional_expr(L, get_coercion(to_environment(L, 1), to_expr(L, 2), to_name_ext(L, 3))); }
|
||||||
|
static int get_coercion_to_sort(lua_State * L) { return push_optional_expr(L, get_coercion_to_sort(to_environment(L, 1), to_expr(L, 2))); }
|
||||||
|
static int get_coercion_to_fun(lua_State * L) { return push_optional_expr(L, get_coercion_to_fun(to_environment(L, 1), to_expr(L, 2))); }
|
||||||
|
static int get_user_coercions(lua_State * L) {
|
||||||
|
buffer<std::pair<expr, name>> r;
|
||||||
|
get_user_coercions(to_environment(L, 1), to_expr(L, 2), r);
|
||||||
|
lua_newtable(L);
|
||||||
|
int i = 1;
|
||||||
|
for (auto p : r) {
|
||||||
|
lua_newtable(L);
|
||||||
|
push_expr(L, p.first);
|
||||||
|
lua_rawseti(L, -2, 1);
|
||||||
|
push_name(L, p.second);
|
||||||
|
lua_rawseti(L, -2, 2);
|
||||||
|
lua_rawseti(L, -2, i);
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void open_coercion(lua_State * L) {
|
||||||
|
SET_GLOBAL_FUN(add_coercion, "add_coercion");
|
||||||
|
SET_GLOBAL_FUN(is_coercion, "is_coercion");
|
||||||
|
SET_GLOBAL_FUN(has_coercions_from, "has_coercions_from");
|
||||||
|
SET_GLOBAL_FUN(has_coercions_to, "has_coercions_to");
|
||||||
|
SET_GLOBAL_FUN(get_coercion, "get_coercion");
|
||||||
|
SET_GLOBAL_FUN(get_coercion_to_sort, "get_coercion_to_sort");
|
||||||
|
SET_GLOBAL_FUN(get_coercion_to_fun, "get_coercion_to_fun");
|
||||||
|
SET_GLOBAL_FUN(get_user_coercions, "get_user_coercions");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ Author: Leonardo de Moura
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include "util/lua.h"
|
||||||
#include "kernel/environment.h"
|
#include "kernel/environment.h"
|
||||||
#include "library/expr_pair.h"
|
#include "library/expr_pair.h"
|
||||||
#include "library/io_state.h"
|
#include "library/io_state.h"
|
||||||
|
@ -60,4 +61,6 @@ optional<expr> get_coercion_to_fun(environment const & env, expr const & C);
|
||||||
\remark The most recent coercions occur first.
|
\remark The most recent coercions occur first.
|
||||||
*/
|
*/
|
||||||
bool get_user_coercions(environment const & env, expr const & C, buffer<std::pair<expr, name>> & result);
|
bool get_user_coercions(environment const & env, expr const & C, buffer<std::pair<expr, name>> & result);
|
||||||
|
|
||||||
|
void open_coercion(lua_State * L);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,14 @@ Author: Leonardo de Moura
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
static environment get_global_environment(lua_State * L);
|
static environment get_global_environment(lua_State * L);
|
||||||
io_state * get_io_state(lua_State * L);
|
io_state * get_io_state_ptr(lua_State * L);
|
||||||
io_state get_tmp_io_state(lua_State * L);
|
io_state get_tmp_io_state(lua_State * L);
|
||||||
|
io_state get_io_state(lua_State * L) {
|
||||||
|
if (io_state * ios = get_io_state_ptr(L))
|
||||||
|
return *ios;
|
||||||
|
else
|
||||||
|
return get_tmp_io_state(L);
|
||||||
|
}
|
||||||
|
|
||||||
// Level
|
// Level
|
||||||
DECL_UDATA(level)
|
DECL_UDATA(level)
|
||||||
|
@ -983,7 +989,7 @@ static char g_formatter_key;
|
||||||
static formatter g_simple_formatter = mk_simple_formatter();
|
static formatter g_simple_formatter = mk_simple_formatter();
|
||||||
|
|
||||||
optional<formatter> get_global_formatter_core(lua_State * L) {
|
optional<formatter> get_global_formatter_core(lua_State * L) {
|
||||||
io_state * io = get_io_state(L);
|
io_state * io = get_io_state_ptr(L);
|
||||||
if (io != nullptr) {
|
if (io != nullptr) {
|
||||||
return optional<formatter>(io->get_formatter());
|
return optional<formatter>(io->get_formatter());
|
||||||
} else {
|
} else {
|
||||||
|
@ -1009,7 +1015,7 @@ formatter get_global_formatter(lua_State * L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_global_formatter(lua_State * L, formatter const & fmt) {
|
void set_global_formatter(lua_State * L, formatter const & fmt) {
|
||||||
io_state * io = get_io_state(L);
|
io_state * io = get_io_state_ptr(L);
|
||||||
if (io != nullptr) {
|
if (io != nullptr) {
|
||||||
io->set_formatter(fmt);
|
io->set_formatter(fmt);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1020,7 +1026,7 @@ void set_global_formatter(lua_State * L, formatter const & fmt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_formatter(lua_State * L) {
|
static int get_formatter(lua_State * L) {
|
||||||
io_state * io = get_io_state(L);
|
io_state * io = get_io_state_ptr(L);
|
||||||
if (io != nullptr) {
|
if (io != nullptr) {
|
||||||
return push_formatter(L, io->get_formatter());
|
return push_formatter(L, io->get_formatter());
|
||||||
} else {
|
} else {
|
||||||
|
@ -1168,10 +1174,8 @@ static int import_modules(environment const & env, lua_State * L, int s) {
|
||||||
|
|
||||||
if (nargs > s + 1 && is_io_state(L, s+2))
|
if (nargs > s + 1 && is_io_state(L, s+2))
|
||||||
return push_environment(L, import_modules(env, mnames.size(), mnames.data(), num_threads, to_io_state(L, s+2)));
|
return push_environment(L, import_modules(env, mnames.size(), mnames.data(), num_threads, to_io_state(L, s+2)));
|
||||||
else if (io_state * ios = get_io_state(L))
|
|
||||||
return push_environment(L, import_modules(env, mnames.size(), mnames.data(), num_threads, *ios));
|
|
||||||
else
|
else
|
||||||
return push_environment(L, import_modules(env, mnames.size(), mnames.data(), num_threads, get_tmp_io_state(L)));
|
return push_environment(L, import_modules(env, mnames.size(), mnames.data(), num_threads, get_io_state(L)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int import_modules(lua_State * L) {
|
static int import_modules(lua_State * L) {
|
||||||
|
@ -1304,7 +1308,7 @@ static void print(io_state * ios, bool reg, char const * msg) {
|
||||||
/** \brief Thread safe version of print function */
|
/** \brief Thread safe version of print function */
|
||||||
static int print(lua_State * L, int start, bool reg) {
|
static int print(lua_State * L, int start, bool reg) {
|
||||||
lock_guard<mutex> lock(g_print_mutex);
|
lock_guard<mutex> lock(g_print_mutex);
|
||||||
io_state * ios = get_io_state(L);
|
io_state * ios = get_io_state_ptr(L);
|
||||||
int n = lua_gettop(L);
|
int n = lua_gettop(L);
|
||||||
int i;
|
int i;
|
||||||
lua_getglobal(L, "tostring");
|
lua_getglobal(L, "tostring");
|
||||||
|
@ -1370,7 +1374,7 @@ void set_global_io_state(lua_State * L, io_state & ios) {
|
||||||
|
|
||||||
set_io_state::set_io_state(lua_State * L, io_state & st) {
|
set_io_state::set_io_state(lua_State * L, io_state & st) {
|
||||||
m_state = L;
|
m_state = L;
|
||||||
m_prev = get_io_state(L);
|
m_prev = get_io_state_ptr(L);
|
||||||
lua_pushlightuserdata(m_state, static_cast<void *>(&g_set_state_key));
|
lua_pushlightuserdata(m_state, static_cast<void *>(&g_set_state_key));
|
||||||
lua_pushlightuserdata(m_state, &st);
|
lua_pushlightuserdata(m_state, &st);
|
||||||
lua_settable(m_state, LUA_REGISTRYINDEX);
|
lua_settable(m_state, LUA_REGISTRYINDEX);
|
||||||
|
@ -1389,7 +1393,7 @@ set_io_state::~set_io_state() {
|
||||||
set_global_options(m_state, m_prev->get_options());
|
set_global_options(m_state, m_prev->get_options());
|
||||||
}
|
}
|
||||||
|
|
||||||
io_state * get_io_state(lua_State * L) {
|
io_state * get_io_state_ptr(lua_State * L) {
|
||||||
lua_pushlightuserdata(L, static_cast<void *>(&g_set_state_key));
|
lua_pushlightuserdata(L, static_cast<void *>(&g_set_state_key));
|
||||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
if (lua_islightuserdata(L, -1)) {
|
if (lua_islightuserdata(L, -1)) {
|
||||||
|
|
|
@ -74,6 +74,7 @@ public:
|
||||||
\brief Return the Lean state object associated with the given Lua state.
|
\brief Return the Lean state object associated with the given Lua state.
|
||||||
Return nullptr is there is none.
|
Return nullptr is there is none.
|
||||||
*/
|
*/
|
||||||
io_state * get_io_state(lua_State * L);
|
io_state * get_io_state_ptr(lua_State * L);
|
||||||
|
io_state get_io_state(lua_State * L);
|
||||||
void open_io_state(lua_State * L);
|
void open_io_state(lua_State * L);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ Author: Leonardo de Moura
|
||||||
#include "util/script_state.h"
|
#include "util/script_state.h"
|
||||||
#include "library/kernel_bindings.h"
|
#include "library/kernel_bindings.h"
|
||||||
#include "library/resolve_macro.h"
|
#include "library/resolve_macro.h"
|
||||||
// #include "library/substitution.h"
|
#include "library/coercion.h"
|
||||||
// #include "library/fo_unify.h"
|
// #include "library/fo_unify.h"
|
||||||
// #include "library/hop_match.h"
|
// #include "library/hop_match.h"
|
||||||
// #include "library/placeholder.h"
|
// #include "library/placeholder.h"
|
||||||
|
@ -17,7 +17,7 @@ namespace lean {
|
||||||
inline void open_core_module(lua_State * L) {
|
inline void open_core_module(lua_State * L) {
|
||||||
open_kernel_module(L);
|
open_kernel_module(L);
|
||||||
open_resolve_macro(L);
|
open_resolve_macro(L);
|
||||||
// open_substitution(L);
|
open_coercion(L);
|
||||||
// open_fo_unify(L);
|
// open_fo_unify(L);
|
||||||
// open_placeholder(L);
|
// open_placeholder(L);
|
||||||
// open_hop_match(L);
|
// open_hop_match(L);
|
||||||
|
|
Loading…
Reference in a new issue