diff --git a/src/frontends/lean/lean_pp.cpp b/src/frontends/lean/lean_pp.cpp index 06e6c0076..fa8a01255 100644 --- a/src/frontends/lean/lean_pp.cpp +++ b/src/frontends/lean/lean_pp.cpp @@ -704,8 +704,7 @@ class pp_fn { } result pp(expr const & e, unsigned depth, bool main = false) { - if (m_interrupted) - throw interrupted(); + check_interrupted(m_interrupted); if (!is_atomic(e) && (m_num_steps > m_max_steps || depth > m_max_depth)) { return pp_ellipsis(); } else { @@ -817,6 +816,7 @@ public: class pp_formatter_cell : public formatter_cell { frontend const & m_frontend; interruptable_ptr m_pp_fn; + volatile bool m_interrupted; format pp(expr const & e, options const & opts) { pp_fn fn(m_frontend, opts); @@ -830,6 +830,7 @@ class pp_formatter_cell : public formatter_cell { bool first = true; expr c2 = context_to_lambda(c, e); while (is_fake_context(c2)) { + check_interrupted(m_interrupted); name n1 = get_unused_name(c2); format entry = format{format(n1), space(), colon(), space(), pp(fake_context_domain(c2), opts)}; expr val = fake_context_value(c2); @@ -865,6 +866,7 @@ class pp_formatter_cell : public formatter_cell { expr it1 = t; expr it2 = v; while (is_pi(it1) && is_lambda(it2)) { + check_interrupted(m_interrupted); if (abst_domain(it1) != abst_domain(it2)) return pp_definition(kwd, n, t, v, opts); it1 = abst_body(it1); @@ -901,6 +903,7 @@ class pp_formatter_cell : public formatter_cell { public: pp_formatter_cell(frontend const & fe): m_frontend(fe) { + m_interrupted = false; } virtual ~pp_formatter_cell() { @@ -920,6 +923,7 @@ public: } else { expr c2 = context_to_lambda(c, e); while (is_fake_context(c2)) { + check_interrupted(m_interrupted); expr const & rest = fake_context_rest(c2); name n1 = get_unused_name(rest); c2 = instantiate_with_closed(rest, mk_constant(n1)); @@ -952,6 +956,7 @@ public: std::for_each(env.begin_objects(), env.end_objects(), [&](object const & obj) { + check_interrupted(m_interrupted); if (first) first = false; else r += line(); r += operator()(obj, opts); }); @@ -960,6 +965,7 @@ public: virtual void set_interrupt(bool flag) { m_pp_fn.set_interrupt(flag); + m_interrupted = flag; } }; diff --git a/src/kernel/normalize.cpp b/src/kernel/normalize.cpp index 70b1f561e..d9a40726f 100644 --- a/src/kernel/normalize.cpp +++ b/src/kernel/normalize.cpp @@ -128,8 +128,7 @@ class normalizer::imp { /** \brief Normalize the expression \c a in a context composed of stack \c s and \c k binders. */ svalue normalize(expr const & a, value_stack const & s, unsigned k) { flet l(m_depth, m_depth+1); - if (m_interrupted) - throw interrupted(); + check_interrupted(m_interrupted); if (m_depth > m_max_depth) throw kernel_exception(m_env, "normalizer maximum recursion depth exceeded"); bool shared = false; diff --git a/src/kernel/type_check.cpp b/src/kernel/type_check.cpp index a36c6b373..ed7733ae7 100644 --- a/src/kernel/type_check.cpp +++ b/src/kernel/type_check.cpp @@ -61,8 +61,7 @@ public: } expr infer_type(expr const & e, context const & ctx) { - if (m_interrupted) - throw interrupted(); + check_interrupted(m_interrupted); bool shared = false; if (is_shared(e)) { shared = true; diff --git a/src/library/metavar_env.cpp b/src/library/metavar_env.cpp index ca14117a0..2451e337e 100644 --- a/src/library/metavar_env.cpp +++ b/src/library/metavar_env.cpp @@ -391,8 +391,7 @@ bool metavar_env::is_simple_ho_match(expr const & e1, expr const & e2, context c \c e2 when none of them are metavariables. */ void metavar_env::unify_core(expr const & e1, expr const & e2, context const & ctx) { - if (m_interrupted) - throw interrupted(); + check_interrupted(m_interrupted); lean_assert(!is_metavar(e1)); lean_assert(!is_metavar(e2)); if (e1 == e2) { diff --git a/src/util/exception.h b/src/util/exception.h index a3eea9286..c1cc7f8b3 100644 --- a/src/util/exception.h +++ b/src/util/exception.h @@ -45,4 +45,9 @@ public: virtual ~interrupted() noexcept {} virtual char const * what() const noexcept { return "interrupted"; } }; +/** \brief Throw interrupted exception iff flag is true. */ +inline void check_interrupted(bool flag) { + if (flag) + throw interrupted(); +} }