fix(frontends/lean): priority expressions parser
This commit is contained in:
parent
8b8267c7ce
commit
4248ad644d
4 changed files with 46 additions and 2 deletions
|
@ -21,6 +21,8 @@ Author: Leonardo de Moura
|
|||
#include "library/explicit.h"
|
||||
#include "library/reducible.h"
|
||||
#include "library/coercion.h"
|
||||
#include "library/choice.h"
|
||||
#include "library/replace_visitor.h"
|
||||
#include "library/class.h"
|
||||
#include "library/abbreviation.h"
|
||||
#include "library/unfold_macros.h"
|
||||
|
@ -298,6 +300,24 @@ struct decl_attributes {
|
|||
m_has_multiple_instances = false;
|
||||
}
|
||||
|
||||
struct elim_choice_fn : public replace_visitor {
|
||||
name m_prio_ns;
|
||||
elim_choice_fn():m_prio_ns(get_priority_namespace()) {}
|
||||
|
||||
virtual expr visit_macro(expr const & e) {
|
||||
if (is_choice(e)) {
|
||||
for (unsigned i = 0; i < get_num_choices(e); i++) {
|
||||
expr const & c = get_choice(e, i);
|
||||
if (is_constant(c) && const_name(c).get_prefix() == m_prio_ns)
|
||||
return c;
|
||||
}
|
||||
throw exception("invalid priority expression, it contains overloaded symbols");
|
||||
} else {
|
||||
return replace_visitor::visit_macro(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
optional<unsigned> parse_instance_priority(parser & p) {
|
||||
if (p.curr_is_token(get_priority_tk())) {
|
||||
p.next();
|
||||
|
@ -305,6 +325,7 @@ struct decl_attributes {
|
|||
environment env = open_priority_aliases(open_num_notation(p.env()));
|
||||
parser::local_scope scope(p, env);
|
||||
expr val = p.parse_expr();
|
||||
val = elim_choice_fn()(val);
|
||||
val = normalize(p.env(), val);
|
||||
if (optional<mpz> mpz_val = to_num(val)) {
|
||||
if (!mpz_val->is_unsigned_int())
|
||||
|
|
|
@ -452,8 +452,11 @@ environment open_prec_aliases(environment const & env) {
|
|||
return overwrite_aliases(env, prec, name());
|
||||
}
|
||||
|
||||
name get_priority_namespace() {
|
||||
return name("std", "priority");
|
||||
}
|
||||
|
||||
environment open_priority_aliases(environment const & env) {
|
||||
name prio("std", "priority");
|
||||
return overwrite_aliases(env, prio, name());
|
||||
return overwrite_aliases(env, get_priority_namespace(), name());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,4 +111,5 @@ environment open_num_notation(environment const & env);
|
|||
environment open_prec_aliases(environment const & env);
|
||||
/** \brief Open 'std.priority' aliases */
|
||||
environment open_priority_aliases(environment const & env);
|
||||
name get_priority_namespace();
|
||||
}
|
||||
|
|
19
tests/lean/run/priority_test.lean
Normal file
19
tests/lean/run/priority_test.lean
Normal file
|
@ -0,0 +1,19 @@
|
|||
open nat
|
||||
|
||||
structure foo [class] :=
|
||||
(a : nat) (b : nat)
|
||||
|
||||
definition i1 [instance] [priority default+1] : foo :=
|
||||
foo.mk 1 1
|
||||
|
||||
definition i2 [instance] : foo :=
|
||||
foo.mk 2 2
|
||||
|
||||
example : foo.a = 1 :=
|
||||
rfl
|
||||
|
||||
definition i3 [instance] [priority default+2] : foo :=
|
||||
foo.mk 3 3
|
||||
|
||||
example : foo.a = 3 :=
|
||||
rfl
|
Loading…
Reference in a new issue