feat(extra): add extension that demonstrates how to parse 'templates'

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-11-19 15:56:44 -08:00
parent 6989f1f9ba
commit 20c6789d1c
5 changed files with 81 additions and 8 deletions

View file

@ -56,7 +56,7 @@ static int parse_lean_expr(lua_State * L) {
3. (string, env, options, formatter?) : Everything is explicitly provided in this
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) {
ro_environment env(L); // get global environment
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 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) {
rw_environment env(L); // get global environment
parse_lean_cmds_core(L, env);

View file

@ -81,28 +81,41 @@ int equal(lua_State * L, int idx1, int idx2) {
#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) {
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) {
int result = luaL_loadfile(L, fname);
if (result)
throw lua_exception(lua_tostring(L, -1));
check_result(L, result);
exec(L);
}
void dostring(lua_State * L, char const * str) {
int result = luaL_loadstring(L, str);
if (result)
throw lua_exception(lua_tostring(L, -1));
check_result(L, result);
exec(L);
}
void pcall(lua_State * L, int nargs, int nresults, int errorfun) {
int result = lua_pcall(L, nargs, nresults, errorfun);
if (result)
throw lua_exception(lua_tostring(L, -1));
check_result(L, result);
}
int safe_function_wrapper(lua_State * L, lua_CFunction f){

View file

@ -17,6 +17,7 @@ void dostring(lua_State * L, char const * str);
void pcall(lua_State * L, int nargs, int nresults, int errorfun);
int lessthan(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.
*/

5
src/extra/README.md Normal file
View file

@ -0,0 +1,5 @@
Extra functionality
-------------------
This directory contains several Lua scripts that provide additional
functionality to Lean.

View 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