2013-11-15 23:55:15 +00:00
|
|
|
/*
|
|
|
|
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 <sstream>
|
2013-11-27 03:15:49 +00:00
|
|
|
#include "util/lua.h"
|
2013-11-27 22:57:33 +00:00
|
|
|
#include "util/script_state.h"
|
2013-11-27 03:15:49 +00:00
|
|
|
#include "util/sexpr/options.h"
|
2013-12-30 19:20:23 +00:00
|
|
|
#include "kernel/io_state.h"
|
2013-11-27 03:15:49 +00:00
|
|
|
#include "library/kernel_bindings.h"
|
2014-01-02 21:14:21 +00:00
|
|
|
#include "library/io_state_stream.h"
|
2013-11-15 23:55:15 +00:00
|
|
|
#include "frontends/lean/parser.h"
|
2013-11-27 22:57:33 +00:00
|
|
|
#include "frontends/lean/frontend.h"
|
2013-12-09 01:33:18 +00:00
|
|
|
#include "frontends/lean/pp.h"
|
2013-11-15 23:55:15 +00:00
|
|
|
|
|
|
|
namespace lean {
|
|
|
|
/** \see parse_lean_expr */
|
2013-12-13 00:33:31 +00:00
|
|
|
static int parse_lean_expr_core(lua_State * L, rw_shared_environment const & env, io_state & st) {
|
2013-11-15 23:55:15 +00:00
|
|
|
char const * src = luaL_checkstring(L, 1);
|
|
|
|
std::istringstream in(src);
|
2013-11-27 22:57:33 +00:00
|
|
|
script_state S = to_script_state(L);
|
2013-11-27 23:40:37 +00:00
|
|
|
expr r;
|
|
|
|
S.exec_unprotected([&]() {
|
|
|
|
r = parse_expr(env, st, in, &S);
|
|
|
|
});
|
|
|
|
return push_expr(L, r);
|
2013-11-15 23:55:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** \see parse_lean_expr */
|
2013-12-13 00:33:31 +00:00
|
|
|
static int parse_lean_expr_core(lua_State * L, rw_shared_environment const & env) {
|
2013-11-21 23:51:29 +00:00
|
|
|
io_state * io = get_io_state(L);
|
|
|
|
if (io == nullptr) {
|
2013-12-09 01:33:18 +00:00
|
|
|
io_state s(get_global_options(L), mk_pp_formatter(env));
|
2013-11-21 23:51:29 +00:00
|
|
|
return parse_lean_expr_core(L, env, s);
|
2013-11-15 23:55:15 +00:00
|
|
|
} else {
|
2013-11-21 23:51:29 +00:00
|
|
|
return parse_lean_expr_core(L, env, *io);
|
2013-11-15 23:55:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int parse_lean_expr(lua_State * L) {
|
|
|
|
/*
|
|
|
|
The parse_lean_expr function in the Lua API supports different calling arguments:
|
|
|
|
1. (string) : simplest form, it is just a string in Lean default syntax.
|
|
|
|
The string is parsed using the global environment in the Lua registry.
|
|
|
|
If the Lua registry does not contain an environment, then commands fails.
|
|
|
|
|
|
|
|
It also uses the global state object in the registry. If there is no
|
|
|
|
state object, it will tries to create one using the global options and formatter
|
|
|
|
in the registry.
|
|
|
|
|
|
|
|
It returns a Lean expression.
|
|
|
|
|
|
|
|
2. (string, env) : similar to the previous one, but the environment is explicitly
|
|
|
|
provided.
|
|
|
|
|
|
|
|
3. (string, env, options, formatter?) : Everything is explicitly provided in this
|
|
|
|
version. We also support a variation where the formmater is omitted.
|
|
|
|
*/
|
2013-11-19 23:56:44 +00:00
|
|
|
int nargs = get_nonnil_top(L);
|
2013-11-15 23:55:15 +00:00
|
|
|
if (nargs == 1) {
|
2013-12-13 00:33:31 +00:00
|
|
|
rw_shared_environment env(L); // get global environment
|
2013-11-15 23:55:15 +00:00
|
|
|
return parse_lean_expr_core(L, env);
|
|
|
|
} else {
|
2013-12-13 00:33:31 +00:00
|
|
|
rw_shared_environment env(L, 2);
|
2013-11-15 23:55:15 +00:00
|
|
|
if (nargs == 2) {
|
|
|
|
return parse_lean_expr_core(L, env);
|
|
|
|
} else {
|
|
|
|
options opts = to_options(L, 3);
|
2013-12-09 01:33:18 +00:00
|
|
|
formatter fmt = nargs == 3 ? mk_pp_formatter(env) : to_formatter(L, 4);
|
2013-11-21 23:51:29 +00:00
|
|
|
io_state st(opts, fmt);
|
2013-11-15 23:55:15 +00:00
|
|
|
return parse_lean_expr_core(L, env, st);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \see parse_lean_cmds */
|
2013-12-13 00:33:31 +00:00
|
|
|
static void parse_lean_cmds_core(lua_State * L, rw_shared_environment const & env, io_state & st) {
|
2013-11-15 23:55:15 +00:00
|
|
|
char const * src = luaL_checkstring(L, 1);
|
|
|
|
std::istringstream in(src);
|
2013-11-27 22:57:33 +00:00
|
|
|
script_state S = to_script_state(L);
|
2013-11-27 23:40:37 +00:00
|
|
|
S.exec_unprotected([&]() {
|
|
|
|
parse_commands(env, st, in, &S);
|
|
|
|
});
|
2013-11-15 23:55:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** \see parse_lean_cmds */
|
2013-12-13 00:33:31 +00:00
|
|
|
static void parse_lean_cmds_core(lua_State * L, rw_shared_environment const & env) {
|
2013-11-21 23:51:29 +00:00
|
|
|
io_state * io = get_io_state(L);
|
|
|
|
if (io == nullptr) {
|
2013-12-09 01:33:18 +00:00
|
|
|
io_state s(get_global_options(L), mk_pp_formatter(env));
|
2013-11-21 23:51:29 +00:00
|
|
|
parse_lean_cmds_core(L, env, s);
|
|
|
|
set_global_options(L, s.get_options());
|
2013-11-15 23:55:15 +00:00
|
|
|
} else {
|
2013-11-21 23:51:29 +00:00
|
|
|
parse_lean_cmds_core(L, env, *io);
|
2013-11-15 23:55:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int parse_lean_cmds(lua_State * L) {
|
|
|
|
/*
|
|
|
|
The parse_lean_cmds function reads a sequence of Lean commands from the input string.
|
|
|
|
The supported calling arguments are equal to the ones used in parse_lean_expr.
|
|
|
|
The main difference is the function result. When calling with explicit options
|
|
|
|
the function returns an updated set of options. Otherwise it does not return anything.
|
|
|
|
*/
|
2013-11-19 23:56:44 +00:00
|
|
|
int nargs = get_nonnil_top(L);
|
2013-11-15 23:55:15 +00:00
|
|
|
if (nargs == 1) {
|
2013-12-12 19:19:09 +00:00
|
|
|
rw_shared_environment env(L); // get global environment
|
2013-11-15 23:55:15 +00:00
|
|
|
parse_lean_cmds_core(L, env);
|
|
|
|
return 0;
|
|
|
|
} else {
|
2013-12-12 19:19:09 +00:00
|
|
|
rw_shared_environment env(L, 2);
|
2013-11-15 23:55:15 +00:00
|
|
|
if (nargs == 2) {
|
|
|
|
parse_lean_cmds_core(L, env);
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
options opts = to_options(L, 3);
|
2013-12-09 01:33:18 +00:00
|
|
|
formatter fmt = nargs == 3 ? mk_pp_formatter(env) : to_formatter(L, 4);
|
2013-11-21 23:51:29 +00:00
|
|
|
io_state st(opts, fmt);
|
2013-11-15 23:55:15 +00:00
|
|
|
parse_lean_cmds_core(L, env, st);
|
|
|
|
push_options(L, st.get_options());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-27 22:57:33 +00:00
|
|
|
static int mk_environment(lua_State * L) {
|
2013-12-18 22:37:55 +00:00
|
|
|
environment env;
|
2014-01-02 21:37:50 +00:00
|
|
|
io_state ios = init_frontend(env);
|
2013-12-18 22:37:55 +00:00
|
|
|
return push_environment(L, env);
|
2013-11-27 22:57:33 +00:00
|
|
|
}
|
|
|
|
|
2013-12-09 01:33:18 +00:00
|
|
|
static int mk_lean_formatter(lua_State * L) {
|
|
|
|
return push_formatter(L, mk_pp_formatter(to_environment(L, 1)));
|
|
|
|
}
|
|
|
|
|
2014-01-08 01:36:27 +00:00
|
|
|
static int is_explicit(lua_State * L) {
|
|
|
|
ro_shared_environment env(L, 1);
|
|
|
|
lua_pushboolean(L, is_explicit(env, to_name_ext(L, 2)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-11-15 23:55:15 +00:00
|
|
|
void open_frontend_lean(lua_State * L) {
|
2013-12-20 03:08:10 +00:00
|
|
|
open_macros(L);
|
2013-12-09 01:33:18 +00:00
|
|
|
SET_GLOBAL_FUN(mk_environment, "environment");
|
|
|
|
SET_GLOBAL_FUN(mk_lean_formatter, "lean_formatter");
|
|
|
|
SET_GLOBAL_FUN(parse_lean_expr, "parse_lean");
|
|
|
|
SET_GLOBAL_FUN(parse_lean_cmds, "parse_lean_cmds");
|
2014-01-08 01:36:27 +00:00
|
|
|
SET_GLOBAL_FUN(is_explicit, "is_explicit");
|
2013-11-27 22:57:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void register_frontend_lean_module() {
|
|
|
|
script_state::register_module(open_frontend_lean);
|
2013-11-15 23:55:15 +00:00
|
|
|
}
|
|
|
|
}
|