feat(extra): add extension that demonstrates how to parse 'templates'
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
6989f1f9ba
commit
20c6789d1c
5 changed files with 81 additions and 8 deletions
|
@ -56,7 +56,7 @@ static int parse_lean_expr(lua_State * L) {
|
||||||
3. (string, env, options, formatter?) : Everything is explicitly provided in this
|
3. (string, env, options, formatter?) : Everything is explicitly provided in this
|
||||||
version. We also support a variation where the formmater is omitted.
|
version. We also support a variation where the formmater is omitted.
|
||||||
*/
|
*/
|
||||||
int nargs = lua_gettop(L);
|
int nargs = get_nonnil_top(L);
|
||||||
if (nargs == 1) {
|
if (nargs == 1) {
|
||||||
ro_environment env(L); // get global environment
|
ro_environment env(L); // get global environment
|
||||||
return parse_lean_expr_core(L, env);
|
return parse_lean_expr_core(L, env);
|
||||||
|
@ -100,7 +100,7 @@ static int parse_lean_cmds(lua_State * L) {
|
||||||
The main difference is the function result. When calling with explicit options
|
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.
|
the function returns an updated set of options. Otherwise it does not return anything.
|
||||||
*/
|
*/
|
||||||
int nargs = lua_gettop(L);
|
int nargs = get_nonnil_top(L);
|
||||||
if (nargs == 1) {
|
if (nargs == 1) {
|
||||||
rw_environment env(L); // get global environment
|
rw_environment env(L); // get global environment
|
||||||
parse_lean_cmds_core(L, env);
|
parse_lean_cmds_core(L, env);
|
||||||
|
|
|
@ -81,28 +81,41 @@ int equal(lua_State * L, int idx1, int idx2) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_nonnil_top(lua_State * L) {
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
while (top > 0 && lua_isnil(L, top))
|
||||||
|
top--;
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
|
||||||
static void exec(lua_State * L) {
|
static void exec(lua_State * L) {
|
||||||
pcall(L, 0, LUA_MULTRET, 0);
|
pcall(L, 0, LUA_MULTRET, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_result(lua_State * L, int result) {
|
||||||
|
if (result) {
|
||||||
|
if (is_justification(L, -1))
|
||||||
|
throw elaborator_exception(to_justification(L, -1));
|
||||||
|
else
|
||||||
|
throw lua_exception(lua_tostring(L, -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dofile(lua_State * L, char const * fname) {
|
void dofile(lua_State * L, char const * fname) {
|
||||||
int result = luaL_loadfile(L, fname);
|
int result = luaL_loadfile(L, fname);
|
||||||
if (result)
|
check_result(L, result);
|
||||||
throw lua_exception(lua_tostring(L, -1));
|
|
||||||
exec(L);
|
exec(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dostring(lua_State * L, char const * str) {
|
void dostring(lua_State * L, char const * str) {
|
||||||
int result = luaL_loadstring(L, str);
|
int result = luaL_loadstring(L, str);
|
||||||
if (result)
|
check_result(L, result);
|
||||||
throw lua_exception(lua_tostring(L, -1));
|
|
||||||
exec(L);
|
exec(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcall(lua_State * L, int nargs, int nresults, int errorfun) {
|
void pcall(lua_State * L, int nargs, int nresults, int errorfun) {
|
||||||
int result = lua_pcall(L, nargs, nresults, errorfun);
|
int result = lua_pcall(L, nargs, nresults, errorfun);
|
||||||
if (result)
|
check_result(L, result);
|
||||||
throw lua_exception(lua_tostring(L, -1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int safe_function_wrapper(lua_State * L, lua_CFunction f){
|
int safe_function_wrapper(lua_State * L, lua_CFunction f){
|
||||||
|
|
|
@ -17,6 +17,7 @@ void dostring(lua_State * L, char const * str);
|
||||||
void pcall(lua_State * L, int nargs, int nresults, int errorfun);
|
void pcall(lua_State * L, int nargs, int nresults, int errorfun);
|
||||||
int lessthan(lua_State * L, int idx1, int idx2);
|
int lessthan(lua_State * L, int idx1, int idx2);
|
||||||
int equal(lua_State * L, int idx1, int idx2);
|
int equal(lua_State * L, int idx1, int idx2);
|
||||||
|
int get_nonnil_top(lua_State * L);
|
||||||
/**
|
/**
|
||||||
\brief Wrapper for invoking function f, and catching Lean exceptions.
|
\brief Wrapper for invoking function f, and catching Lean exceptions.
|
||||||
*/
|
*/
|
||||||
|
|
5
src/extra/README.md
Normal file
5
src/extra/README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
Extra functionality
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
This directory contains several Lua scripts that provide additional
|
||||||
|
functionality to Lean.
|
54
src/extra/parse_lean_tpl.lua
Normal file
54
src/extra/parse_lean_tpl.lua
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
-- Parse a template expression string 'str'.
|
||||||
|
-- The string 'str' contains placeholders of the form 'a::i', where 'i' is a numeral.
|
||||||
|
-- The placeholders are replaced with values from the array 'args'.
|
||||||
|
-- See 'test' function for an example.
|
||||||
|
function parse_lean_tpl(str, args, env, opts, fmt)
|
||||||
|
assert(type(str) == "string")
|
||||||
|
assert(type(args) == "table")
|
||||||
|
assert(env == nil or is_environment(env))
|
||||||
|
if #args == 0 then
|
||||||
|
return parse_lean(str, env, opts, fmt)
|
||||||
|
else
|
||||||
|
-- Create the string "fun (a::1 : type-of-args[1]) ... (a::n : type-of-args[n]), $str",
|
||||||
|
-- where n is the size of args
|
||||||
|
local inferer = type_inferer(env)
|
||||||
|
local tbl = {"fun"}
|
||||||
|
for i = 1, #args do
|
||||||
|
table.insert(tbl, " (a::")
|
||||||
|
table.insert(tbl, i)
|
||||||
|
table.insert(tbl, " : ")
|
||||||
|
table.insert(tbl, tostring(inferer(args[i])))
|
||||||
|
table.insert(tbl, ")")
|
||||||
|
end
|
||||||
|
table.insert(tbl, ", ")
|
||||||
|
table.insert(tbl, str)
|
||||||
|
local new_str = table.concat(tbl)
|
||||||
|
local r = parse_lean(new_str, env, opts, fmt)
|
||||||
|
for i = 1, #args do
|
||||||
|
assert(r:is_lambda())
|
||||||
|
local n, d, body = r:fields()
|
||||||
|
r = body:instantiate(args[i])
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local test = function()
|
||||||
|
local env = environment()
|
||||||
|
-- Load environment with some definitions
|
||||||
|
parse_lean_cmds([[
|
||||||
|
Variables a b : Real
|
||||||
|
Variable f : Real -> Real
|
||||||
|
Variable g : Real -> Real -> Real
|
||||||
|
]], env)
|
||||||
|
local a, b, g = Consts("a, b, g")
|
||||||
|
local t1 = parse_lean_tpl("a::1 + (f a::2) - 10 + a::2", {a, g(b, a)}, env)
|
||||||
|
print(t1)
|
||||||
|
local t2 = parse_lean_tpl("f (a::1 + 1)", {g(b, b)}, env)
|
||||||
|
print(t2)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not pcall(debug.getlocal, 4, 1) then
|
||||||
|
-- Main file
|
||||||
|
test()
|
||||||
|
end
|
Loading…
Reference in a new issue