feat(frontends/lean): add let-expr pretty printer, reduce default indentation to 2
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
d31cde473e
commit
43eba857cb
8 changed files with 97 additions and 62 deletions
|
@ -10,6 +10,7 @@ Author: Leonardo de Moura
|
||||||
#include "library/aliases.h"
|
#include "library/aliases.h"
|
||||||
#include "library/scoped_ext.h"
|
#include "library/scoped_ext.h"
|
||||||
#include "library/coercion.h"
|
#include "library/coercion.h"
|
||||||
|
#include "library/expr_pair.h"
|
||||||
#include "frontends/lean/pp.h"
|
#include "frontends/lean/pp.h"
|
||||||
#include "frontends/lean/pp_options.h"
|
#include "frontends/lean/pp_options.h"
|
||||||
#include "frontends/lean/token_table.h"
|
#include "frontends/lean/token_table.h"
|
||||||
|
@ -25,6 +26,9 @@ static format g_pi_n_fmt = highlight_keyword(format("Π"));
|
||||||
static format g_pi_fmt = highlight_keyword(format("Pi"));
|
static format g_pi_fmt = highlight_keyword(format("Pi"));
|
||||||
static format g_arrow_n_fmt = highlight_keyword(format("\u2192"));
|
static format g_arrow_n_fmt = highlight_keyword(format("\u2192"));
|
||||||
static format g_arrow_fmt = highlight_keyword(format("->"));
|
static format g_arrow_fmt = highlight_keyword(format("->"));
|
||||||
|
static format g_let_fmt = highlight_keyword(format("let"));
|
||||||
|
static format g_in_fmt = highlight_keyword(format("in"));
|
||||||
|
static format g_assign_fmt = highlight_keyword(format(":="));
|
||||||
|
|
||||||
name pretty_fn::mk_metavar_name(name const & m) {
|
name pretty_fn::mk_metavar_name(name const & m) {
|
||||||
if (auto it = m_purify_meta_table.find(m))
|
if (auto it = m_purify_meta_table.find(m))
|
||||||
|
@ -272,14 +276,51 @@ auto pretty_fn::pp_pi(expr const & e) -> result {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto pretty_fn::pp_let(expr e) -> result {
|
||||||
|
buffer<expr_pair> decls;
|
||||||
|
while (true) {
|
||||||
|
if (!is_let_macro(e))
|
||||||
|
break;
|
||||||
|
e = let_macro_arg(e);
|
||||||
|
if (!is_app(e) || !is_lambda(app_fn(e)))
|
||||||
|
break;
|
||||||
|
expr v = app_arg(e);
|
||||||
|
auto p = binding_body_fresh(app_fn(e), true);
|
||||||
|
decls.emplace_back(p.second, v);
|
||||||
|
e = p.first;
|
||||||
|
}
|
||||||
|
if (decls.empty())
|
||||||
|
return pp(e);
|
||||||
|
format r = g_let_fmt;
|
||||||
|
unsigned sz = decls.size();
|
||||||
|
for (unsigned i = 0; i < sz; i++) {
|
||||||
|
auto const & d = decls[i];
|
||||||
|
format beg = i == 0 ? space() : line();
|
||||||
|
format sep = i < sz - 1 ? comma() : format();
|
||||||
|
name const & n = local_pp_name(d.first);
|
||||||
|
format t = pp_child(mlocal_type(d.first), 0).first;
|
||||||
|
format v = pp_child(d.second, 0).first;
|
||||||
|
r += nest(3 + 1, compose(beg, group(format{format(n), space(),
|
||||||
|
colon(), nest(n.size() + 1 + 1 + 1, compose(space(), t)), space(), g_assign_fmt,
|
||||||
|
nest(m_indent, format{line(), v, sep})})));
|
||||||
|
}
|
||||||
|
format b = pp_child(e, 0).first;
|
||||||
|
r += format{line(), g_in_fmt, space(), nest(2 + 1, b)};
|
||||||
|
return mk_result(r, 0);
|
||||||
|
}
|
||||||
|
|
||||||
auto pretty_fn::pp_macro(expr const & e) -> result {
|
auto pretty_fn::pp_macro(expr const & e) -> result {
|
||||||
// TODO(Leo): handle let, have macro annotations
|
if (is_let_macro(e)) {
|
||||||
|
return pp_let(e);
|
||||||
|
} else {
|
||||||
|
// TODO(Leo): have macro annotations
|
||||||
// fix macro<->pp interface
|
// fix macro<->pp interface
|
||||||
format r = compose(format("["), format(macro_def(e).get_name()));
|
format r = compose(format("["), format(macro_def(e).get_name()));
|
||||||
for (unsigned i = 0; i < macro_num_args(e); i++)
|
for (unsigned i = 0; i < macro_num_args(e); i++)
|
||||||
r += nest(m_indent, compose(line(), pp_child(macro_arg(e, i), max_bp()).first));
|
r += nest(m_indent, compose(line(), pp_child(macro_arg(e, i), max_bp()).first));
|
||||||
r += format("]");
|
r += format("]");
|
||||||
return mk_result(group(r));
|
return mk_result(group(r));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pretty_fn::pp(expr const & e) -> result {
|
auto pretty_fn::pp(expr const & e) -> result {
|
||||||
|
|
|
@ -62,6 +62,7 @@ private:
|
||||||
result pp_app(expr const & e);
|
result pp_app(expr const & e);
|
||||||
result pp_lambda(expr const & e);
|
result pp_lambda(expr const & e);
|
||||||
result pp_pi(expr const & e);
|
result pp_pi(expr const & e);
|
||||||
|
result pp_let(expr e);
|
||||||
result pp_macro(expr const & e);
|
result pp_macro(expr const & e);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "util/sexpr/options.h"
|
#include "util/sexpr/options.h"
|
||||||
|
|
||||||
#ifndef LEAN_DEFAULT_PP_INDENTATION
|
#ifndef LEAN_DEFAULT_PP_INDENTATION
|
||||||
#define LEAN_DEFAULT_PP_INDENTATION 4
|
#define LEAN_DEFAULT_PP_INDENTATION 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LEAN_DEFAULT_PP_UNICODE
|
#ifndef LEAN_DEFAULT_PP_UNICODE
|
||||||
|
|
|
@ -1,36 +1,29 @@
|
||||||
[let
|
let and_intro : ∀ (p q : Bool),
|
||||||
((λ (and_intro : ∀ (p q : Bool), p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q),
|
p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q :=
|
||||||
[let
|
λ (p q : Bool) (H1 : p) (H2 : q) (c : Bool) (H : p → q → c),
|
||||||
((λ
|
H H1 H2,
|
||||||
(and_elim_left : ∀ (p q : Bool), (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → p),
|
and_elim_left : ∀ (p q : Bool),
|
||||||
[let
|
(λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → p :=
|
||||||
((λ
|
λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q),
|
||||||
(and_elim_right :
|
H p (λ (H1 : p) (H2 : q), H1),
|
||||||
∀ (p q : Bool),
|
and_elim_right : ∀ (p q : Bool),
|
||||||
(λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → q),
|
(λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → q :=
|
||||||
and_intro)
|
λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q),
|
||||||
(λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q),
|
H q (λ (H1 : p) (H2 : q), H2)
|
||||||
H q (λ (H1 : p) (H2 : q), H2)))])
|
in and_intro :
|
||||||
(λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q),
|
|
||||||
H p (λ (H1 : p) (H2 : q), H1)))])
|
|
||||||
(λ (p q : Bool) (H1 : p) (H2 : q) (c : Bool) (H : p → q → c), H H1 H2))] :
|
|
||||||
∀ (p q : Bool),
|
∀ (p q : Bool),
|
||||||
p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q
|
p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q
|
||||||
let1.lean:17:20: error: type mismatch at application
|
let1.lean:17:20: error: type mismatch at application
|
||||||
(λ (and_intro : ∀ (p q : Bool), p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) q p),
|
(λ (and_intro : ∀ (p q : Bool), p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) q p),
|
||||||
[let
|
let and_elim_left : ∀ (p q : Bool),
|
||||||
((λ
|
(λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → p :=
|
||||||
(and_elim_left : ∀ (p q : Bool), (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → p),
|
λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q),
|
||||||
[let
|
H p (λ (H1 : p) (H2 : q), H1),
|
||||||
((λ
|
and_elim_right : ∀ (p q : Bool),
|
||||||
(and_elim_right :
|
(λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → q :=
|
||||||
∀ (p q : Bool),
|
λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q),
|
||||||
(λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → q),
|
H q (λ (H1 : p) (H2 : q), H2)
|
||||||
and_intro)
|
in and_intro)
|
||||||
(λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q),
|
|
||||||
H q (λ (H1 : p) (H2 : q), H2)))])
|
|
||||||
(λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q),
|
|
||||||
H p (λ (H1 : p) (H2 : q), H1)))])
|
|
||||||
(λ (p q : Bool) (H1 : p) (H2 : q) (c : Bool) (H : p → q → c), H H1 H2)
|
(λ (p q : Bool) (H1 : p) (H2 : q) (c : Bool) (H : p → q → c), H H1 H2)
|
||||||
expected type:
|
expected type:
|
||||||
∀ (p q : Bool),
|
∀ (p q : Bool),
|
||||||
|
|
|
@ -3,7 +3,7 @@ precedence `++` : 100
|
||||||
variable N : Type.{1}
|
variable N : Type.{1}
|
||||||
variable f : N → N → N
|
variable f : N → N → N
|
||||||
variable a : N
|
variable a : N
|
||||||
print raw
|
check
|
||||||
let g x y := f x y,
|
let g x y := f x y,
|
||||||
infix + := g,
|
infix + := g,
|
||||||
b : N := a+a,
|
b : N := a+a,
|
||||||
|
|
Loading…
Reference in a new issue