refactor(frontends/lean/elaborator): delete old_elaborator, and create frontend_elaborator class that will be based on library/elaborator/elaborator
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
449454efdb
commit
71ccec5b9e
8 changed files with 134 additions and 341 deletions
|
@ -1,3 +1,3 @@
|
|||
add_library(lean_frontend frontend.cpp operator_info.cpp scanner.cpp parser.cpp pp.cpp
|
||||
notation.cpp elaborator.cpp elaborator_exception.cpp)
|
||||
notation.cpp frontend_elaborator.cpp)
|
||||
target_link_libraries(lean_frontend ${LEAN_LIBS})
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "util/flet.h"
|
||||
#include "util/name_set.h"
|
||||
#include "kernel/normalizer.h"
|
||||
#include "kernel/context.h"
|
||||
#include "kernel/builtin.h"
|
||||
#include "kernel/free_vars.h"
|
||||
#include "kernel/for_each.h"
|
||||
#include "kernel/replace.h"
|
||||
#include "kernel/instantiate.h"
|
||||
#include "kernel/metavar.h"
|
||||
#include "kernel/printer.h"
|
||||
#include "library/placeholder.h"
|
||||
#include "library/update_expr.h"
|
||||
#include "library/expr_pair.h"
|
||||
#include "frontends/lean/frontend.h"
|
||||
#include "frontends/lean/elaborator.h"
|
||||
#include "frontends/lean/elaborator_exception.h"
|
||||
|
||||
namespace lean {
|
||||
static name g_choice_name = name::mk_internal_unique_name();
|
||||
static expr g_choice = mk_constant(g_choice_name);
|
||||
static format g_assignment_fmt = format(":=");
|
||||
static format g_unification_u_fmt = format("\u2248");
|
||||
static format g_unification_fmt = format("=?=");
|
||||
|
||||
expr mk_choice(unsigned num_fs, expr const * fs) {
|
||||
lean_assert(num_fs >= 2);
|
||||
return mk_eq(g_choice, mk_app(num_fs, fs));
|
||||
}
|
||||
|
||||
bool is_choice(expr const & e) {
|
||||
return is_eq(e) && eq_lhs(e) == g_choice;
|
||||
}
|
||||
|
||||
unsigned get_num_choices(expr const & e) {
|
||||
lean_assert(is_choice(e));
|
||||
return num_args(eq_rhs(e));
|
||||
}
|
||||
|
||||
expr const & get_choice(expr const & e, unsigned i) {
|
||||
lean_assert(is_choice(e));
|
||||
return arg(eq_rhs(e), i);
|
||||
}
|
||||
|
||||
old_elaborator::old_elaborator(frontend const & ) {}
|
||||
old_elaborator::~old_elaborator() {}
|
||||
expr old_elaborator::operator()(expr const & e) { return e; }
|
||||
expr old_elaborator::operator()(expr const & e, expr const & /* expected_type */) { return e; }
|
||||
expr const & old_elaborator::get_original(expr const & e) const { return e; }
|
||||
void old_elaborator::set_interrupt(bool ) {}
|
||||
void old_elaborator::clear() {}
|
||||
environment const & old_elaborator::get_environment() const {
|
||||
static thread_local environment g_env;
|
||||
return g_env;
|
||||
}
|
||||
void old_elaborator::display(std::ostream & ) const {}
|
||||
format old_elaborator::pp(formatter &, options const &) const { return format(); }
|
||||
void old_elaborator::print(imp * ptr) { lean_assert(ptr); }
|
||||
bool old_elaborator::has_constraints() const { return false; }
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include <vector>
|
||||
#include "frontends/lean/elaborator_exception.h"
|
||||
#include "frontends/lean/elaborator.h"
|
||||
|
||||
namespace lean {
|
||||
format pp_elaborator_state(formatter fmt, old_elaborator const & elb, options const & opts) {
|
||||
unsigned indent = get_pp_indent(opts);
|
||||
format r;
|
||||
if (elb.has_constraints()) {
|
||||
format elb_fmt = elb.pp(fmt, opts);
|
||||
r += compose(line(), format("Elaborator state"));
|
||||
r += nest(indent, compose(line(), elb_fmt));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
format pp(formatter fmt, context const & ctx, std::vector<expr> const & exprs, std::vector<expr> const & types, options const & opts) {
|
||||
unsigned indent = get_pp_indent(opts);
|
||||
lean_assert(exprs.size() == types.size());
|
||||
auto it1 = exprs.begin();
|
||||
auto it2 = types.begin();
|
||||
format r;
|
||||
for (; it1 != exprs.end(); ++it1, ++it2) {
|
||||
r += nest(indent, compose(line(), group(format{fmt(ctx, *it1, false, opts), space(), colon(),
|
||||
nest(indent, format{line(), fmt(ctx, *it2, false, opts)})})));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
format old_elaborator_exception::pp(formatter const & fmt, options const & opts) const {
|
||||
unsigned indent = get_pp_indent(opts);
|
||||
format expr_fmt = fmt(get_context(), get_expr(), false, opts);
|
||||
format r;
|
||||
r += format{format(what()), space(), format("at term")};
|
||||
r += nest(indent, compose(line(), expr_fmt));
|
||||
r += pp_elaborator_state(fmt, get_elaborator(), opts);
|
||||
return r;
|
||||
}
|
||||
|
||||
format overload_exception::pp(formatter const & fmt, options const & opts) const {
|
||||
context const & ctx = get_context();
|
||||
format r;
|
||||
r += format{format(what()), line(), format("Candidates:")};
|
||||
r += ::lean::pp(fmt, ctx, get_fs(), get_f_types(), opts);
|
||||
r += format{line(), format("Arguments:")};
|
||||
r += ::lean::pp(fmt, ctx, get_args(), get_arg_types(), opts);
|
||||
return r;
|
||||
}
|
||||
|
||||
format unification_app_mismatch_exception::pp(formatter const & fmt, options const & opts) const {
|
||||
unsigned indent = get_pp_indent(opts);
|
||||
auto const & ctx = get_context();
|
||||
expr const & app = get_expr();
|
||||
auto args_it = get_args().begin();
|
||||
auto args_end = get_args().end();
|
||||
auto types_it = get_types().begin();
|
||||
format app_fmt = fmt(ctx, app, false, opts);
|
||||
format r = format{format(what()), nest(indent, compose(line(), app_fmt))};
|
||||
format fun_type_fmt = fmt(ctx, *types_it, false, opts);
|
||||
r += compose(line(), format("Function type:"));
|
||||
r += nest(indent, compose(line(), fun_type_fmt));
|
||||
++args_it;
|
||||
++types_it;
|
||||
if (get_args().size() > 2)
|
||||
r += compose(line(), format("Arguments types:"));
|
||||
else
|
||||
r += compose(line(), format("Argument type:"));
|
||||
for (; args_it != args_end; ++args_it, ++types_it) {
|
||||
format arg_fmt = fmt(ctx, *args_it, false, opts);
|
||||
format type_fmt = fmt(ctx, *types_it, false, opts);
|
||||
r += nest(indent, compose(line(), group(format{arg_fmt, space(), colon(), nest(indent, format{line(), type_fmt})})));
|
||||
}
|
||||
r += pp_elaborator_state(fmt, get_elaborator(), opts);
|
||||
return r;
|
||||
}
|
||||
|
||||
format unification_type_mismatch_exception::pp(formatter const & fmt, options const & opts) const {
|
||||
unsigned indent = get_pp_indent(opts);
|
||||
auto const & ctx = get_context();
|
||||
expr const & e = get_expr();
|
||||
expr const & p = get_processed_expr();
|
||||
expr const & exp = get_expected_type();
|
||||
expr const & given = get_given_type();
|
||||
format r = format{format(what()), nest(indent, compose(line(), fmt(ctx, e, false, opts)))};
|
||||
if (p != e) {
|
||||
r += compose(line(), format("Term after elaboration:"));
|
||||
r += nest(indent, compose(line(), fmt(ctx, p, false, opts)));
|
||||
}
|
||||
r += compose(line(), format("Expected type:"));
|
||||
r += nest(indent, compose(line(), fmt(ctx, exp, false, opts)));
|
||||
if (given) {
|
||||
r += compose(line(), format("Got:"));
|
||||
r += nest(indent, compose(line(), fmt(ctx, given, false, opts)));
|
||||
}
|
||||
r += pp_elaborator_state(fmt, get_elaborator(), opts);
|
||||
return r;
|
||||
}
|
||||
|
||||
regular const & operator<<(regular const & out, old_elaborator_exception const & ex) {
|
||||
options const & opts = out.m_state.get_options();
|
||||
out.m_state.get_regular_channel().get_stream() << mk_pair(ex.pp(out.m_state.get_formatter(), opts), opts);
|
||||
return out;
|
||||
}
|
||||
|
||||
diagnostic const & operator<<(diagnostic const & out, old_elaborator_exception const & ex) {
|
||||
options const & opts = out.m_state.get_options();
|
||||
out.m_state.get_diagnostic_channel().get_stream() << mk_pair(ex.pp(out.m_state.get_formatter(), opts), opts);
|
||||
return out;
|
||||
}
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "kernel/kernel_exception.h"
|
||||
#include "library/state.h"
|
||||
#include "frontends/lean/elaborator.h"
|
||||
|
||||
namespace lean {
|
||||
/**
|
||||
\brief Base class for elaborator exceptions.
|
||||
|
||||
\remark We reuse kernel exceptions to sign type errors during
|
||||
elaboration. Perhaps we should wrap them as elaborator exceptions.
|
||||
*/
|
||||
class old_elaborator_exception : public exception {
|
||||
protected:
|
||||
old_elaborator m_elb;
|
||||
context m_context;
|
||||
expr m_expr;
|
||||
public:
|
||||
old_elaborator_exception(old_elaborator const & elb, context const & ctx, expr const & e):m_elb(elb), m_context(ctx), m_expr(e) {}
|
||||
virtual ~old_elaborator_exception() noexcept {}
|
||||
old_elaborator const & get_elaborator() const { return m_elb; }
|
||||
expr const & get_expr() const { return m_expr; }
|
||||
context const & get_context() const { return m_context; }
|
||||
virtual format pp(formatter const & fmt, options const & opts) const;
|
||||
};
|
||||
|
||||
class invalid_placeholder_exception : public old_elaborator_exception {
|
||||
public:
|
||||
invalid_placeholder_exception(old_elaborator const & elb, context const & ctx, expr const & e):old_elaborator_exception(elb, ctx, e) {}
|
||||
virtual char const * what() const noexcept { return "invalid placeholder occurrence, placeholder cannot be used as application head"; }
|
||||
};
|
||||
|
||||
class unsolved_placeholder_exception : public old_elaborator_exception {
|
||||
public:
|
||||
unsolved_placeholder_exception(old_elaborator const & elb, context const & ctx, expr const & e):old_elaborator_exception(elb, ctx, e) {}
|
||||
virtual char const * what() const noexcept { return "unsolved placeholder"; }
|
||||
};
|
||||
|
||||
class unification_app_mismatch_exception : public old_elaborator_exception {
|
||||
std::vector<expr> m_args;
|
||||
std::vector<expr> m_types;
|
||||
public:
|
||||
unification_app_mismatch_exception(old_elaborator const & elb, context const & ctx, expr const & s,
|
||||
std::vector<expr> const & args, std::vector<expr> const & types):
|
||||
old_elaborator_exception(elb, ctx, s),
|
||||
m_args(args),
|
||||
m_types(types) {}
|
||||
virtual ~unification_app_mismatch_exception() {}
|
||||
std::vector<expr> const & get_args() const { return m_args; }
|
||||
std::vector<expr> const & get_types() const { return m_types; }
|
||||
virtual char const * what() const noexcept { return "application type mismatch during term elaboration"; }
|
||||
virtual format pp(formatter const & fmt, options const & opts) const;
|
||||
};
|
||||
|
||||
class unification_type_mismatch_exception : public old_elaborator_exception {
|
||||
expr m_processed_expr;
|
||||
expr m_expected_type;
|
||||
expr m_given_type;
|
||||
public:
|
||||
unification_type_mismatch_exception(old_elaborator const & elb, context const & ctx, expr const & s,
|
||||
expr const & processed, expr const & expected, expr const & given):
|
||||
old_elaborator_exception(elb, ctx, s), m_processed_expr(processed), m_expected_type(expected), m_given_type(given) {}
|
||||
virtual ~unification_type_mismatch_exception() {}
|
||||
expr const & get_processed_expr() const { return m_processed_expr; }
|
||||
expr const & get_expected_type() const { return m_expected_type; }
|
||||
expr const & get_given_type() const { return m_given_type; }
|
||||
virtual char const * what() const noexcept { return "type mismatch during term elaboration"; }
|
||||
virtual format pp(formatter const & fmt, options const & opts) const;
|
||||
};
|
||||
|
||||
class overload_exception : public old_elaborator_exception {
|
||||
std::vector<expr> m_fs;
|
||||
std::vector<expr> m_f_types;
|
||||
std::vector<expr> m_args;
|
||||
std::vector<expr> m_arg_types;
|
||||
public:
|
||||
overload_exception(old_elaborator const & elb, context const & ctx, expr const & s,
|
||||
unsigned num_fs, expr const * fs, expr const * ftypes,
|
||||
unsigned num_args, expr const * args, expr const * argtypes):
|
||||
old_elaborator_exception(elb, ctx, s),
|
||||
m_fs(fs, fs + num_fs),
|
||||
m_f_types(ftypes, ftypes + num_fs),
|
||||
m_args(args, args + num_args),
|
||||
m_arg_types(argtypes, argtypes + num_args) {
|
||||
}
|
||||
virtual ~overload_exception() {}
|
||||
std::vector<expr> const & get_fs() const { return m_fs; }
|
||||
std::vector<expr> const & get_f_types() const { return m_f_types; }
|
||||
std::vector<expr> const & get_args() const { return m_args; }
|
||||
std::vector<expr> const & get_arg_types() const { return m_arg_types; }
|
||||
virtual format pp(formatter const & fmt, options const & opts) const;
|
||||
};
|
||||
|
||||
class no_overload_exception : public overload_exception {
|
||||
public:
|
||||
no_overload_exception(old_elaborator const & elb, context const & ctx, expr const & s,
|
||||
unsigned num_fs, expr const * fs, expr const * ftypes,
|
||||
unsigned num_args, expr const * args, expr const * argtypes):
|
||||
overload_exception(elb, ctx, s, num_fs, fs, ftypes, num_args, args, argtypes) {}
|
||||
virtual char const * what() const noexcept { return "application type mismatch, none of the overloads can be used"; }
|
||||
};
|
||||
|
||||
class ambiguous_overload_exception : public overload_exception {
|
||||
public:
|
||||
ambiguous_overload_exception(old_elaborator const & elb, context const & ctx, expr const & s,
|
||||
unsigned num_fs, expr const * fs, expr const * ftypes,
|
||||
unsigned num_args, expr const * args, expr const * argtypes):
|
||||
overload_exception(elb, ctx, s, num_fs, fs, ftypes, num_args, args, argtypes) {}
|
||||
virtual char const * what() const noexcept { return "ambiguous overloads"; }
|
||||
};
|
||||
|
||||
regular const & operator<<(regular const & out, old_elaborator_exception const & ex);
|
||||
diagnostic const & operator<<(diagnostic const & out, old_elaborator_exception const & ex);
|
||||
}
|
88
src/frontends/lean/frontend_elaborator.cpp
Normal file
88
src/frontends/lean/frontend_elaborator.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include "kernel/type_checker.h"
|
||||
#include "library/elaborator/elaborator.h"
|
||||
#include "frontends/lean/frontend.h"
|
||||
#include "frontends/lean/frontend_elaborator.h"
|
||||
|
||||
namespace lean {
|
||||
static name g_choice_name = name::mk_internal_unique_name();
|
||||
static expr g_choice = mk_constant(g_choice_name);
|
||||
static format g_assignment_fmt = format(":=");
|
||||
static format g_unification_u_fmt = format("\u2248");
|
||||
static format g_unification_fmt = format("=?=");
|
||||
|
||||
expr mk_choice(unsigned num_fs, expr const * fs) {
|
||||
lean_assert(num_fs >= 2);
|
||||
return mk_eq(g_choice, mk_app(num_fs, fs));
|
||||
}
|
||||
|
||||
bool is_choice(expr const & e) {
|
||||
return is_eq(e) && eq_lhs(e) == g_choice;
|
||||
}
|
||||
|
||||
unsigned get_num_choices(expr const & e) {
|
||||
lean_assert(is_choice(e));
|
||||
return num_args(eq_rhs(e));
|
||||
}
|
||||
|
||||
expr const & get_choice(expr const & e, unsigned i) {
|
||||
lean_assert(is_choice(e));
|
||||
return arg(eq_rhs(e), i);
|
||||
}
|
||||
|
||||
class frontend_elaborator::imp {
|
||||
frontend const & m_frontend;
|
||||
environment const & m_env;
|
||||
type_checker m_type_checker;
|
||||
volatile bool m_interrupted;
|
||||
public:
|
||||
imp(frontend const & fe):
|
||||
m_frontend(fe),
|
||||
m_env(fe.get_environment()),
|
||||
m_type_checker(m_env) {
|
||||
m_interrupted = false;
|
||||
}
|
||||
|
||||
expr elaborate(expr const & e) {
|
||||
// TODO(Leo)
|
||||
return e;
|
||||
}
|
||||
|
||||
std::pair<expr, expr> elaborate(expr const & t, expr const & e) {
|
||||
// TODO(Leo)
|
||||
return mk_pair(t, e);
|
||||
}
|
||||
|
||||
expr const & get_original(expr const & e) {
|
||||
// TODO(Leo)
|
||||
return e;
|
||||
}
|
||||
|
||||
void set_interrupt(bool f) {
|
||||
m_interrupted = f;
|
||||
m_type_checker.set_interrupt(f);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
// TODO(Leo)
|
||||
}
|
||||
|
||||
environment const & get_environment() const {
|
||||
return m_env;
|
||||
}
|
||||
};
|
||||
|
||||
frontend_elaborator::frontend_elaborator(frontend const & fe):m_ptr(new imp(fe)) {}
|
||||
frontend_elaborator::~frontend_elaborator() {}
|
||||
expr frontend_elaborator::operator()(expr const & e) { return m_ptr->elaborate(e); }
|
||||
std::pair<expr, expr> frontend_elaborator::operator()(expr const & t, expr const & e) { return m_ptr->elaborate(t, e); }
|
||||
expr const & frontend_elaborator::get_original(expr const & e) const { return m_ptr->get_original(e); }
|
||||
void frontend_elaborator::set_interrupt(bool f) { m_ptr->set_interrupt(f); }
|
||||
void frontend_elaborator::clear() { m_ptr->clear(); }
|
||||
environment const & frontend_elaborator::get_environment() const { return m_ptr->get_environment(); }
|
||||
}
|
|
@ -12,20 +12,29 @@ Author: Leonardo de Moura
|
|||
namespace lean {
|
||||
class frontend;
|
||||
/**
|
||||
\brief Expression elaborator, it is responsible for "filling" holes
|
||||
\brief Expression elaborator for the Lean default frontend, it is responsible for "filling" holes
|
||||
in terms left by the user. This is the main module resposible for computing
|
||||
the value of implicit arguments.
|
||||
the value of implicit arguments. It is based on the general purpose elaborator defined at
|
||||
library/elaborator/elaborator.h
|
||||
*/
|
||||
class old_elaborator {
|
||||
class frontend_elaborator {
|
||||
class imp;
|
||||
std::shared_ptr<imp> m_ptr;
|
||||
static void print(imp * ptr);
|
||||
public:
|
||||
explicit old_elaborator(frontend const & fe);
|
||||
~old_elaborator();
|
||||
explicit frontend_elaborator(frontend const & fe);
|
||||
~frontend_elaborator();
|
||||
|
||||
/**
|
||||
\brief Elaborate the given expression.
|
||||
*/
|
||||
expr operator()(expr const & e);
|
||||
expr operator()(expr const & e, expr const & expected_type);
|
||||
/**
|
||||
\brief Elaborate the given type and expression. The typeof(e) == t.
|
||||
This information is used by the elaborator. The result is a new
|
||||
elaborated type and expression.
|
||||
*/
|
||||
std::pair<expr, expr> operator()(expr const & t, expr const & e);
|
||||
|
||||
/**
|
||||
\brief If \c e is an expression instantiated by the elaborator, then it
|
||||
|
@ -41,12 +50,8 @@ public:
|
|||
void clear();
|
||||
|
||||
environment const & get_environment() const;
|
||||
|
||||
void display(std::ostream & out) const;
|
||||
format pp(formatter & f, options const & o) const;
|
||||
|
||||
bool has_constraints() const;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Create a choice expression for the given functions.
|
||||
It is used to mark which functions can be used in a particular application.
|
|
@ -29,9 +29,9 @@ Author: Leonardo de Moura
|
|||
#include "library/arith/arith.h"
|
||||
#include "library/state.h"
|
||||
#include "library/placeholder.h"
|
||||
#include "library/elaborator/elaborator_exception.h"
|
||||
#include "frontends/lean/frontend.h"
|
||||
#include "frontends/lean/elaborator.h"
|
||||
#include "frontends/lean/elaborator_exception.h"
|
||||
#include "frontends/lean/frontend_elaborator.h"
|
||||
#include "frontends/lean/parser.h"
|
||||
#include "frontends/lean/scanner.h"
|
||||
#include "frontends/lean/notation.h"
|
||||
|
@ -115,24 +115,24 @@ class parser::imp {
|
|||
typedef std::pair<unsigned, unsigned> pos_info;
|
||||
typedef expr_map<pos_info> expr_pos_info;
|
||||
typedef buffer<std::tuple<pos_info, name, expr, bool>> bindings_buffer;
|
||||
frontend m_frontend;
|
||||
scanner m_scanner;
|
||||
old_elaborator m_elaborator;
|
||||
scanner::token m_curr;
|
||||
bool m_use_exceptions;
|
||||
bool m_interactive;
|
||||
bool m_found_errors;
|
||||
local_decls m_local_decls;
|
||||
unsigned m_num_local_decls;
|
||||
expr_pos_info m_expr_pos_info;
|
||||
pos_info m_last_cmd_pos;
|
||||
frontend m_frontend;
|
||||
scanner m_scanner;
|
||||
frontend_elaborator m_elaborator;
|
||||
scanner::token m_curr;
|
||||
bool m_use_exceptions;
|
||||
bool m_interactive;
|
||||
bool m_found_errors;
|
||||
local_decls m_local_decls;
|
||||
unsigned m_num_local_decls;
|
||||
expr_pos_info m_expr_pos_info;
|
||||
pos_info m_last_cmd_pos;
|
||||
// Reference to temporary parser used to process import command.
|
||||
// We need this reference to be able to interrupt it.
|
||||
interruptable_ptr<parser> m_import_parser;
|
||||
interruptable_ptr<normalizer> m_normalizer;
|
||||
|
||||
bool m_verbose;
|
||||
bool m_show_errors;
|
||||
bool m_verbose;
|
||||
bool m_show_errors;
|
||||
|
||||
/** \brief Exception used to track parsing erros, it does not leak outside of this class. */
|
||||
struct parser_error : public exception {
|
||||
|
@ -1030,14 +1030,14 @@ class parser::imp {
|
|||
/** \brief Auxiliary method used for parsing definitions and theorems. */
|
||||
void parse_def_core(bool is_definition) {
|
||||
next();
|
||||
expr type, val;
|
||||
expr pre_type, pre_val;
|
||||
name id = check_identifier_next("invalid definition, identifier expected");
|
||||
bindings_buffer bindings;
|
||||
if (curr_is_colon()) {
|
||||
next();
|
||||
type = m_elaborator(parse_expr());
|
||||
pre_type = parse_expr();
|
||||
check_assign_next("invalid definition, ':=' expected");
|
||||
val = m_elaborator(parse_expr(), type);
|
||||
pre_val = parse_expr();
|
||||
} else {
|
||||
mk_scope scope(*this);
|
||||
parse_object_bindings(bindings);
|
||||
|
@ -1045,9 +1045,12 @@ class parser::imp {
|
|||
expr type_body = parse_expr();
|
||||
check_assign_next("invalid definition, ':=' expected");
|
||||
expr val_body = parse_expr();
|
||||
type = m_elaborator(mk_abstraction(false, bindings, type_body));
|
||||
val = m_elaborator(mk_abstraction(true, bindings, val_body), type);
|
||||
pre_type = mk_abstraction(false, bindings, type_body);
|
||||
pre_val = mk_abstraction(true, bindings, val_body);
|
||||
}
|
||||
auto type_val_pair = m_elaborator(pre_type, pre_val);
|
||||
expr type = type_val_pair.first;
|
||||
expr val = type_val_pair.second;
|
||||
if (is_definition) {
|
||||
m_frontend.add_definition(id, type, val);
|
||||
if (m_verbose)
|
||||
|
@ -1519,10 +1522,13 @@ class parser::imp {
|
|||
sync();
|
||||
}
|
||||
|
||||
void display_error(old_elaborator_exception const & ex) {
|
||||
void display_error(elaborator_exception const &) {
|
||||
#if 0
|
||||
// TODO(Leo)
|
||||
display_error_pos(m_elaborator.get_original(ex.get_expr()));
|
||||
regular(m_frontend) << " " << ex << endl;
|
||||
sync();
|
||||
#endif
|
||||
}
|
||||
|
||||
void updt_options() {
|
||||
|
@ -1586,7 +1592,7 @@ public:
|
|||
display_error(ex);
|
||||
if (m_use_exceptions)
|
||||
throw;
|
||||
} catch (old_elaborator_exception & ex) {
|
||||
} catch (elaborator_exception & ex) {
|
||||
m_found_errors = true;
|
||||
if (m_show_errors)
|
||||
display_error(ex);
|
||||
|
|
|
@ -25,7 +25,7 @@ Author: Leonardo de Moura
|
|||
#include "frontends/lean/pp.h"
|
||||
#include "frontends/lean/frontend.h"
|
||||
#include "frontends/lean/coercion.h"
|
||||
#include "frontends/lean/elaborator.h"
|
||||
#include "frontends/lean/frontend_elaborator.h"
|
||||
|
||||
#ifndef LEAN_DEFAULT_PP_MAX_DEPTH
|
||||
#define LEAN_DEFAULT_PP_MAX_DEPTH std::numeric_limits<unsigned>::max()
|
||||
|
|
Loading…
Reference in a new issue