fix(frontends/lean): more precise position information for infix operators

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-01-07 13:16:18 -08:00
parent 8f3c97ca98
commit 0f1737d62c
5 changed files with 30 additions and 35 deletions

View file

@ -146,26 +146,23 @@ expr parser_imp::parse_prefix(operator_info const & op) {
} }
/** \brief Parse a user defined postfix operator. */ /** \brief Parse a user defined postfix operator. */
expr parser_imp::parse_postfix(expr const & left, operator_info const & op) { expr parser_imp::parse_postfix(expr const & left, operator_info const & op, pos_info const & op_pos) {
return mk_application(op, pos(), left); return mk_application(op, op_pos, left);
} }
/** \brief Parse a user defined infix operator. */ /** \brief Parse a user defined infix operator. */
expr parser_imp::parse_infix(expr const & left, operator_info const & op) { expr parser_imp::parse_infix(expr const & left, operator_info const & op, pos_info const & op_pos) {
auto p = pos(); return mk_application(op, op_pos, {left, parse_expr(op.get_precedence()+1)});
return mk_application(op, p, {left, parse_expr(op.get_precedence()+1)});
} }
/** \brief Parse a user defined infix-left operator. */ /** \brief Parse a user defined infix-left operator. */
expr parser_imp::parse_infixl(expr const & left, operator_info const & op) { expr parser_imp::parse_infixl(expr const & left, operator_info const & op, pos_info const & op_pos) {
auto p = pos(); return mk_application(op, op_pos, {left, parse_expr(op.get_precedence())});
return mk_application(op, p, {left, parse_expr(op.get_precedence())});
} }
/** \brief Parse a user defined infix-right operator. */ /** \brief Parse a user defined infix-right operator. */
expr parser_imp::parse_infixr(expr const & left, operator_info const & op) { expr parser_imp::parse_infixr(expr const & left, operator_info const & op, pos_info const & op_pos) {
auto p = pos(); return mk_application(op, op_pos, {left, parse_expr(op.get_precedence()-1)});
return mk_application(op, p, {left, parse_expr(op.get_precedence()-1)});
} }
/** /**
@ -204,8 +201,7 @@ expr parser_imp::parse_mixfixl(operator_info const & op) {
} }
/** \brief Parse user defined mixfixr operator. It has the form: _ ID ... _ ID */ /** \brief Parse user defined mixfixr operator. It has the form: _ ID ... _ ID */
expr parser_imp::parse_mixfixr(expr const & left, operator_info const & op) { expr parser_imp::parse_mixfixr(expr const & left, operator_info const & op, pos_info const & op_pos) {
auto p = pos();
buffer<expr> args; buffer<expr> args;
args.push_back(left); args.push_back(left);
auto parts = op.get_op_name_parts(); auto parts = op.get_op_name_parts();
@ -216,17 +212,16 @@ expr parser_imp::parse_mixfixr(expr const & left, operator_info const & op) {
check_op_part(*it); check_op_part(*it);
++it; ++it;
} }
return mk_application(op, p, args); return mk_application(op, op_pos, args);
} }
/** \brief Parse user defined mixfixr operator. It has the form: _ ID ... _ ID _ */ /** \brief Parse user defined mixfixr operator. It has the form: _ ID ... _ ID _ */
expr parser_imp::parse_mixfixo(expr const & left, operator_info const & op) { expr parser_imp::parse_mixfixo(expr const & left, operator_info const & op, pos_info const & op_pos) {
auto p = pos();
buffer<expr> args; buffer<expr> args;
args.push_back(left); args.push_back(left);
args.push_back(parse_expr(op.get_precedence())); args.push_back(parse_expr(op.get_precedence()));
parse_mixfix_args(op.get_op_name_parts(), op.get_precedence(), args); parse_mixfix_args(op.get_op_name_parts(), op.get_precedence(), args);
return mk_application(op, p, args); return mk_application(op, op_pos, args);
} }
/** \brief Parse user defined mixfixc operator. It has the form: ID _ ID ... _ ID */ /** \brief Parse user defined mixfixc operator. It has the form: ID _ ID ... _ ID */
@ -553,12 +548,12 @@ expr parser_imp::parse_led_id(expr const & left) {
operator_info op = find_led(m_env, id); operator_info op = find_led(m_env, id);
if (op) { if (op) {
switch (op.get_fixity()) { switch (op.get_fixity()) {
case fixity::Infix: return parse_infix(left, op); case fixity::Infix: return parse_infix(left, op, p);
case fixity::Infixl: return parse_infixl(left, op); case fixity::Infixl: return parse_infixl(left, op, p);
case fixity::Infixr: return parse_infixr(left, op); case fixity::Infixr: return parse_infixr(left, op, p);
case fixity::Mixfixr: return parse_mixfixr(left, op); case fixity::Mixfixr: return parse_mixfixr(left, op, p);
case fixity::Mixfixo: return parse_mixfixo(left, op); case fixity::Mixfixo: return parse_mixfixo(left, op, p);
case fixity::Postfix: return parse_postfix(left, op); case fixity::Postfix: return parse_postfix(left, op, p);
default: lean_unreachable(); // LCOV_EXCL_LINE default: lean_unreachable(); // LCOV_EXCL_LINE
} }
} else { } else {

View file

@ -264,15 +264,15 @@ private:
expr mk_application(operator_info const & op, pos_info const & pos, expr const & arg); expr mk_application(operator_info const & op, pos_info const & pos, expr const & arg);
expr mk_application(operator_info const & op, pos_info const & pos, buffer<expr> const & args); expr mk_application(operator_info const & op, pos_info const & pos, buffer<expr> const & args);
expr parse_prefix(operator_info const & op); expr parse_prefix(operator_info const & op);
expr parse_postfix(expr const & left, operator_info const & op); expr parse_postfix(expr const & left, operator_info const & op, pos_info const & op_pos);
expr parse_infix(expr const & left, operator_info const & op); expr parse_infix(expr const & left, operator_info const & op, pos_info const & op_pos);
expr parse_infixl(expr const & left, operator_info const & op); expr parse_infixl(expr const & left, operator_info const & op, pos_info const & op_pos);
expr parse_infixr(expr const & left, operator_info const & op); expr parse_infixr(expr const & left, operator_info const & op, pos_info const & op_pos);
void check_op_part(name const & op_part); void check_op_part(name const & op_part);
void parse_mixfix_args(list<name> const & ops, unsigned prec, buffer<expr> & args); void parse_mixfix_args(list<name> const & ops, unsigned prec, buffer<expr> & args);
expr parse_mixfixl(operator_info const & op); expr parse_mixfixl(operator_info const & op);
expr parse_mixfixr(expr const & left, operator_info const & op); expr parse_mixfixr(expr const & left, operator_info const & op, pos_info const & op_pos);
expr parse_mixfixo(expr const & left, operator_info const & op); expr parse_mixfixo(expr const & left, operator_info const & op, pos_info const & op_pos);
expr parse_mixfixc(operator_info const & op); expr parse_mixfixc(operator_info const & op);
void propagate_position(expr const & e, pos_info p); void propagate_position(expr const & e, pos_info p);
bool is_curr_begin_expr() const; bool is_curr_begin_expr() const;

View file

@ -10,7 +10,7 @@ Error (line: 8, pos: 0) invalid object declaration, environment already has an o
Assumed: b Assumed: b
and a b and a b
Assumed: A Assumed: A
Error (line: 12, pos: 11) type mismatch at application Error (line: 12, pos: 8) type mismatch at application
and a A and a A
Function type: Function type:
Bool -> Bool -> Bool Bool -> Bool -> Bool

View file

@ -16,7 +16,7 @@ Failed to solve
Set: lean::pp::implicit Set: lean::pp::implicit
Failed to solve Failed to solve
⊢ Bool ≺ T ⊢ Bool ≺ T
(line: 9: pos: 15) Type of argument 2 must be convertible to the expected type in the application of (line: 9: pos: 11) Type of argument 2 must be convertible to the expected type in the application of
@myeq2 @myeq2
with arguments: with arguments:
T T

View file

@ -4,25 +4,25 @@
Imported 'Real' Imported 'Real'
Failed to solve Failed to solve
⊢ (?M::0 ≈ Nat::add) ⊕ (?M::0 ≈ Int::add) ⊕ (?M::0 ≈ Real::add) ⊢ (?M::0 ≈ Nat::add) ⊕ (?M::0 ≈ Int::add) ⊕ (?M::0 ≈ Real::add)
(line: 3: pos: 10) Overloading at (line: 3: pos: 8) Overloading at
(Real::add | Int::add | Nat::add) 1 (Real::add | Int::add | Nat::add) 1
Failed to solve Failed to solve
⊢ Bool ≺ ⊢ Bool ≺
(line: 3: pos: 10) Type of argument 2 must be convertible to the expected type in the application of (line: 3: pos: 8) Type of argument 2 must be convertible to the expected type in the application of
Nat::add Nat::add
with arguments: with arguments:
1 1
Failed to solve Failed to solve
⊢ Bool ≺ ⊢ Bool ≺
(line: 3: pos: 10) Type of argument 2 must be convertible to the expected type in the application of (line: 3: pos: 8) Type of argument 2 must be convertible to the expected type in the application of
Int::add Int::add
with arguments: with arguments:
1 1
Failed to solve Failed to solve
⊢ Bool ≺ ⊢ Bool ≺
(line: 3: pos: 10) Type of argument 2 must be convertible to the expected type in the application of (line: 3: pos: 8) Type of argument 2 must be convertible to the expected type in the application of
Real::add Real::add
with arguments: with arguments:
1 1