Add output_channel and state abstractions
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
73262e9786
commit
4fa2468a85
11 changed files with 260 additions and 65 deletions
|
@ -1,3 +1,3 @@
|
||||||
add_library(exprlib basic_thms.cpp deep_copy.cpp max_sharing.cpp toplevel.cpp printer.cpp
|
add_library(exprlib basic_thms.cpp deep_copy.cpp max_sharing.cpp toplevel.cpp printer.cpp
|
||||||
formatter.cpp context_to_lambda.cpp)
|
formatter.cpp context_to_lambda.cpp state.cpp)
|
||||||
target_link_libraries(exprlib ${LEAN_LIBS})
|
target_link_libraries(exprlib ${LEAN_LIBS})
|
||||||
|
|
|
@ -11,23 +11,23 @@ Author: Leonardo de Moura
|
||||||
namespace lean {
|
namespace lean {
|
||||||
class simple_formatter_cell : public formatter_cell {
|
class simple_formatter_cell : public formatter_cell {
|
||||||
public:
|
public:
|
||||||
virtual format operator()(expr const & e) {
|
virtual format operator()(expr const & e, options const & opts) {
|
||||||
std::ostringstream s; s << e; return format(s.str());
|
std::ostringstream s; s << e; return format(s.str());
|
||||||
}
|
}
|
||||||
virtual format operator()(context const & c) {
|
virtual format operator()(context const & c, options const & opts) {
|
||||||
std::ostringstream s; s << c; return format(s.str());
|
std::ostringstream s; s << c; return format(s.str());
|
||||||
}
|
}
|
||||||
virtual format operator()(context const & c, expr const & e, bool format_ctx) {
|
virtual format operator()(context const & c, expr const & e, bool format_ctx, options const & opts) {
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
if (format_ctx)
|
if (format_ctx)
|
||||||
s << c << "|-\n";
|
s << c << "|-\n";
|
||||||
s << mk_pair(e,c);
|
s << mk_pair(e,c);
|
||||||
return format(s.str());
|
return format(s.str());
|
||||||
}
|
}
|
||||||
virtual format operator()(object const & obj) {
|
virtual format operator()(object const & obj, options const & opts) {
|
||||||
std::ostringstream s; s << obj; return format(s.str());
|
std::ostringstream s; s << obj; return format(s.str());
|
||||||
}
|
}
|
||||||
virtual format operator()(environment const & env) {
|
virtual format operator()(environment const & env, options const & opts) {
|
||||||
std::ostringstream s; s << env; return format(s.str());
|
std::ostringstream s; s << env; return format(s.str());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@ Author: Leonardo de Moura
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
class environment;
|
class environment;
|
||||||
|
@ -18,9 +19,9 @@ class formatter_cell {
|
||||||
public:
|
public:
|
||||||
virtual ~formatter_cell() {}
|
virtual ~formatter_cell() {}
|
||||||
/** \brief Format the given expression. */
|
/** \brief Format the given expression. */
|
||||||
virtual format operator()(expr const & e) = 0;
|
virtual format operator()(expr const & e, options const & opts) = 0;
|
||||||
/** \brief Format the given context. */
|
/** \brief Format the given context. */
|
||||||
virtual format operator()(context const & c) = 0;
|
virtual format operator()(context const & c, options const & opts) = 0;
|
||||||
/**
|
/**
|
||||||
\brief Format the given expression with respect to the given
|
\brief Format the given expression with respect to the given
|
||||||
context.
|
context.
|
||||||
|
@ -28,11 +29,11 @@ public:
|
||||||
\remark If format_ctx == false, then the context is not formatted. It just provides names
|
\remark If format_ctx == false, then the context is not formatted. It just provides names
|
||||||
for the free variables
|
for the free variables
|
||||||
*/
|
*/
|
||||||
virtual format operator()(context const & c, expr const & e, bool format_ctx = false) = 0;
|
virtual format operator()(context const & c, expr const & e, bool format_ctx, options const & opts) = 0;
|
||||||
/** \brief Format the given object */
|
/** \brief Format the given object */
|
||||||
virtual format operator()(object const & obj) = 0;
|
virtual format operator()(object const & obj, options const & opts) = 0;
|
||||||
/** \brief Format the given environment */
|
/** \brief Format the given environment */
|
||||||
virtual format operator()(environment const & env) = 0;
|
virtual format operator()(environment const & env, options const & opts) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class formatter {
|
class formatter {
|
||||||
|
@ -40,11 +41,11 @@ class formatter {
|
||||||
public:
|
public:
|
||||||
formatter(formatter_cell * c):m_cell(c) {}
|
formatter(formatter_cell * c):m_cell(c) {}
|
||||||
formatter(std::shared_ptr<formatter_cell> const & c):m_cell(c) {}
|
formatter(std::shared_ptr<formatter_cell> const & c):m_cell(c) {}
|
||||||
format operator()(expr const & e) { return (*m_cell)(e); }
|
format operator()(expr const & e, options const & opts = options()) { return (*m_cell)(e, opts); }
|
||||||
format operator()(context const & c) { return (*m_cell)(c); }
|
format operator()(context const & c, options const & opts = options()) { return (*m_cell)(c, opts); }
|
||||||
format operator()(context const & c, expr const & e, bool format_ctx = false) { return (*m_cell)(c, e, format_ctx); }
|
format operator()(context const & c, expr const & e, bool format_ctx = false, options const & opts = options()) { return (*m_cell)(c, e, format_ctx, opts); }
|
||||||
format operator()(object const & obj) { return (*m_cell)(obj); }
|
format operator()(object const & obj, options const & opts = options()) { return (*m_cell)(obj, opts); }
|
||||||
format operator()(environment const & env) { return (*m_cell)(env); }
|
format operator()(environment const & env, options const & opts = options()) { return (*m_cell)(env, opts); }
|
||||||
};
|
};
|
||||||
|
|
||||||
formatter mk_simple_formatter();
|
formatter mk_simple_formatter();
|
||||||
|
|
40
src/exprlib/state.cpp
Normal file
40
src/exprlib/state.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
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 "state.h"
|
||||||
|
|
||||||
|
namespace lean {
|
||||||
|
state::state():
|
||||||
|
m_formatter(mk_simple_formatter()),
|
||||||
|
m_regular_channel(new stdout_channel()),
|
||||||
|
m_diagnostic_channel(new stderr_channel()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
state::state(options const & opts, formatter const & fmt):
|
||||||
|
m_options(opts),
|
||||||
|
m_formatter(fmt),
|
||||||
|
m_regular_channel(new stdout_channel()),
|
||||||
|
m_diagnostic_channel(new stderr_channel()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
state::~state() {}
|
||||||
|
|
||||||
|
void state::set_regular_channel(std::shared_ptr<output_channel> const & out) {
|
||||||
|
m_regular_channel = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void state::set_diagnostic_channel(std::shared_ptr<output_channel> const & out) {
|
||||||
|
m_diagnostic_channel = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void state::set_options(options const & opts) {
|
||||||
|
m_options = opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void state::set_formatter(formatter const & f) {
|
||||||
|
m_formatter = f;
|
||||||
|
}
|
||||||
|
}
|
72
src/exprlib/state.h
Normal file
72
src/exprlib/state.h
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
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 "output_channel.h"
|
||||||
|
#include "formatter.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
namespace lean {
|
||||||
|
/**
|
||||||
|
\brief State provided to internal lean procedures that need to:
|
||||||
|
1- Access user defined options
|
||||||
|
2- Produce verbosity messages
|
||||||
|
3- Output results
|
||||||
|
4- Produce formatted output
|
||||||
|
*/
|
||||||
|
class state {
|
||||||
|
options m_options;
|
||||||
|
formatter m_formatter;
|
||||||
|
std::shared_ptr<output_channel> m_regular_channel;
|
||||||
|
std::shared_ptr<output_channel> m_diagnostic_channel;
|
||||||
|
public:
|
||||||
|
state();
|
||||||
|
state(options const & opts, formatter const & fmt);
|
||||||
|
~state();
|
||||||
|
|
||||||
|
options get_options() const { return m_options; }
|
||||||
|
formatter get_formatter() const { return m_formatter; }
|
||||||
|
output_channel & get_regular_channel() const { return *m_regular_channel; }
|
||||||
|
output_channel & get_diagnostic_channel() const { return *m_diagnostic_channel; }
|
||||||
|
|
||||||
|
void set_regular_channel(std::shared_ptr<output_channel> const & out);
|
||||||
|
void set_diagnostic_channel(std::shared_ptr<output_channel> const & out);
|
||||||
|
void set_options(options const & opts);
|
||||||
|
void set_formatter(formatter const & f);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct regular {
|
||||||
|
state const & m_state;
|
||||||
|
regular(state const & s):m_state(s) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct diagnostic {
|
||||||
|
state const & m_state;
|
||||||
|
diagnostic(state const & s):m_state(s) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline regular const & operator<<(regular const & out, T const & t) {
|
||||||
|
out.m_state.get_regular_channel().get_stream() << t;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline diagnostic const & operator<<(diagnostic const & out, T const & t) {
|
||||||
|
out.m_state.get_diagnostic_channel().get_stream() << t;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline regular const & operator<<(regular const & out, expr const & e) {
|
||||||
|
out.m_state.get_regular_channel().get_stream() << out.m_state.get_formatter()(e, out.m_state.get_options());
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline diagnostic const & operator<<(diagnostic const & out, expr const & e) {
|
||||||
|
out.m_state.get_diagnostic_channel().get_stream() << out.m_state.get_formatter()(e, out.m_state.get_options());
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ Author: Leonardo de Moura
|
||||||
#include "operator_info.h"
|
#include "operator_info.h"
|
||||||
#include "toplevel.h"
|
#include "toplevel.h"
|
||||||
#include "builtin_notation.h"
|
#include "builtin_notation.h"
|
||||||
|
#include "state.h"
|
||||||
#include "pp.h"
|
#include "pp.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
@ -27,6 +28,7 @@ struct frontend::imp {
|
||||||
operator_table m_led; // led table for Pratt's parser
|
operator_table m_led; // led table for Pratt's parser
|
||||||
expr_to_operator m_expr_to_operator; // map denotations to operators (this is used for pretty printing)
|
expr_to_operator m_expr_to_operator; // map denotations to operators (this is used for pretty printing)
|
||||||
implicit_table m_implicit_table; // track the number of implicit arguments for a symbol.
|
implicit_table m_implicit_table; // track the number of implicit arguments for a symbol.
|
||||||
|
state m_state;
|
||||||
|
|
||||||
bool has_children() const { return m_num_children > 0; }
|
bool has_children() const { return m_num_children > 0; }
|
||||||
void inc_children() { m_num_children++; }
|
void inc_children() { m_num_children++; }
|
||||||
|
@ -168,7 +170,8 @@ struct frontend::imp {
|
||||||
explicit imp(std::shared_ptr<imp> const & parent):
|
explicit imp(std::shared_ptr<imp> const & parent):
|
||||||
m_num_children(0),
|
m_num_children(0),
|
||||||
m_parent(parent),
|
m_parent(parent),
|
||||||
m_env(m_parent->m_env.mk_child()) {
|
m_env(m_parent->m_env.mk_child()),
|
||||||
|
m_state(m_parent->m_state) {
|
||||||
m_parent->inc_children();
|
m_parent->inc_children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,8 +184,11 @@ struct frontend::imp {
|
||||||
frontend::frontend():m_imp(new imp(*this)) {
|
frontend::frontend():m_imp(new imp(*this)) {
|
||||||
init_builtin_notation(*this);
|
init_builtin_notation(*this);
|
||||||
init_toplevel(m_imp->m_env);
|
init_toplevel(m_imp->m_env);
|
||||||
|
m_imp->m_state.set_formatter(mk_pp_formatter(*this));
|
||||||
|
}
|
||||||
|
frontend::frontend(imp * new_ptr):m_imp(new_ptr) {
|
||||||
|
m_imp->m_state.set_formatter(mk_pp_formatter(*this));
|
||||||
}
|
}
|
||||||
frontend::frontend(imp * new_ptr):m_imp(new_ptr) {}
|
|
||||||
frontend::frontend(std::shared_ptr<imp> const & ptr):m_imp(ptr) {}
|
frontend::frontend(std::shared_ptr<imp> const & ptr):m_imp(ptr) {}
|
||||||
frontend::~frontend() {}
|
frontend::~frontend() {}
|
||||||
|
|
||||||
|
@ -223,4 +229,9 @@ void frontend::add_mixfixc(unsigned sz, name const * opns, unsigned p, expr cons
|
||||||
operator_info frontend::find_op_for(expr const & n) const { return m_imp->find_op_for(n); }
|
operator_info frontend::find_op_for(expr const & n) const { return m_imp->find_op_for(n); }
|
||||||
operator_info frontend::find_nud(name const & n) const { return m_imp->find_nud(n); }
|
operator_info frontend::find_nud(name const & n) const { return m_imp->find_nud(n); }
|
||||||
operator_info frontend::find_led(name const & n) const { return m_imp->find_led(n); }
|
operator_info frontend::find_led(name const & n) const { return m_imp->find_led(n); }
|
||||||
|
|
||||||
|
state const & frontend::get_state() const { return m_imp->m_state; }
|
||||||
|
void frontend::set_options(options const & opts) { return m_imp->m_state.set_options(opts); }
|
||||||
|
void frontend::set_regular_channel(std::shared_ptr<output_channel> const & out) { return m_imp->m_state.set_regular_channel(out); }
|
||||||
|
void frontend::set_diagnostic_channel(std::shared_ptr<output_channel> const & out) { return m_imp->m_state.set_diagnostic_channel(out); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ Author: Leonardo de Moura
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
#include "operator_info.h"
|
#include "operator_info.h"
|
||||||
|
#include "state.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
/**
|
/**
|
||||||
|
@ -113,5 +114,16 @@ public:
|
||||||
*/
|
*/
|
||||||
operator_info find_led(name const & n) const;
|
operator_info find_led(name const & n) const;
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@name State management.
|
||||||
|
*/
|
||||||
|
/*@{*/
|
||||||
|
state const & get_state() const;
|
||||||
|
operator state const &() const { return get_state(); }
|
||||||
|
void set_options(options const & opts);
|
||||||
|
void set_regular_channel(std::shared_ptr<output_channel> const & out);
|
||||||
|
void set_diagnostic_channel(std::shared_ptr<output_channel> const & out);
|
||||||
|
/*@}*/
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -793,23 +793,22 @@ public:
|
||||||
|
|
||||||
class pp_formatter_cell : public formatter_cell {
|
class pp_formatter_cell : public formatter_cell {
|
||||||
frontend m_frontend;
|
frontend m_frontend;
|
||||||
options m_options;
|
|
||||||
unsigned m_indent;
|
|
||||||
|
|
||||||
format pp(expr const & e) {
|
format pp(expr const & e, options const & opts) {
|
||||||
return pp_fn(m_frontend, m_options)(e);
|
return pp_fn(m_frontend, opts)(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
format pp(context const & c, expr const & e, bool include_e) {
|
format pp(context const & c, expr const & e, bool include_e, options const & opts) {
|
||||||
|
unsigned indent = get_pp_indent(opts);
|
||||||
format r;
|
format r;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
expr c2 = context_to_lambda(c, e);
|
expr c2 = context_to_lambda(c, e);
|
||||||
while (is_fake_context(c2)) {
|
while (is_fake_context(c2)) {
|
||||||
name n1 = get_unused_name(c2);
|
name n1 = get_unused_name(c2);
|
||||||
format entry = format{format(n1), space(), colon(), space(), pp(fake_context_domain(c2))};
|
format entry = format{format(n1), space(), colon(), space(), pp(fake_context_domain(c2), opts)};
|
||||||
expr val = fake_context_value(c2);
|
expr val = fake_context_value(c2);
|
||||||
if (val)
|
if (val)
|
||||||
entry += format{space(), g_assign_fmt, nest(m_indent, format{line(), pp(val)})};
|
entry += format{space(), g_assign_fmt, nest(indent, format{line(), pp(val, opts)})};
|
||||||
if (first) {
|
if (first) {
|
||||||
r = group(entry);
|
r = group(entry);
|
||||||
first = false;
|
first = false;
|
||||||
|
@ -820,77 +819,77 @@ class pp_formatter_cell : public formatter_cell {
|
||||||
}
|
}
|
||||||
if (include_e) {
|
if (include_e) {
|
||||||
if (first)
|
if (first)
|
||||||
r += format{line(), pp(c2)};
|
r += format{line(), pp(c2, opts)};
|
||||||
else
|
else
|
||||||
r = pp(c2);
|
r = pp(c2, opts);
|
||||||
} else {
|
} else {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
format pp_definition(char const * kwd, name const & n, expr const & t, expr const & v) {
|
format pp_definition(char const * kwd, name const & n, expr const & t, expr const & v, options const & opts) {
|
||||||
|
unsigned indent = get_pp_indent(opts);
|
||||||
format def = format{highlight_command(format(kwd)), space(), format(n), space(), colon(), space(),
|
format def = format{highlight_command(format(kwd)), space(), format(n), space(), colon(), space(),
|
||||||
pp(t), space(), g_assign_fmt, line(), pp(v)};
|
pp(t, opts), space(), g_assign_fmt, line(), pp(v, opts)};
|
||||||
return group(nest(m_indent, def));
|
return group(nest(indent, def));
|
||||||
}
|
}
|
||||||
|
|
||||||
format pp_compact_definition(char const * kwd, name const & n, expr const & t, expr const & v) {
|
format pp_compact_definition(char const * kwd, name const & n, expr const & t, expr const & v, options const & opts) {
|
||||||
expr it1 = t;
|
expr it1 = t;
|
||||||
expr it2 = v;
|
expr it2 = v;
|
||||||
while (is_pi(it1) && is_lambda(it2)) {
|
while (is_pi(it1) && is_lambda(it2)) {
|
||||||
if (abst_domain(it1) != abst_domain(it2))
|
if (abst_domain(it1) != abst_domain(it2))
|
||||||
return pp_definition(kwd, n, t, v);
|
return pp_definition(kwd, n, t, v, opts);
|
||||||
it1 = abst_body(it1);
|
it1 = abst_body(it1);
|
||||||
it2 = abst_body(it2);
|
it2 = abst_body(it2);
|
||||||
}
|
}
|
||||||
if (!is_lambda(v) || is_pi(it1)) {
|
if (!is_lambda(v) || is_pi(it1)) {
|
||||||
return pp_definition(kwd, n, t, v);
|
return pp_definition(kwd, n, t, v, opts);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
lean_assert(is_lambda(v));
|
lean_assert(is_lambda(v));
|
||||||
format def = pp_fn(m_frontend, m_options).pp_definition(v, t);
|
format def = pp_fn(m_frontend, opts).pp_definition(v, t);
|
||||||
return format{highlight_command(format(kwd)), space(), format(n), def};
|
return format{highlight_command(format(kwd)), space(), format(n), def};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
format pp_uvar_decl(object const & obj) {
|
format pp_uvar_decl(object const & obj, options const & opts) {
|
||||||
return format{highlight_command(format(obj.keyword())), space(), format(obj.get_name()), space(), format("\u2265"), space(), ::lean::pp(obj.get_cnstr_level())};
|
return format{highlight_command(format(obj.keyword())), space(), format(obj.get_name()), space(), format("\u2265"), space(), ::lean::pp(obj.get_cnstr_level())};
|
||||||
}
|
}
|
||||||
|
|
||||||
format pp_postulate(object const & obj) {
|
format pp_postulate(object const & obj, options const & opts) {
|
||||||
return format{highlight_command(format(obj.keyword())), space(), format(obj.get_name()), space(), colon(), space(), pp(obj.get_type())};
|
return format{highlight_command(format(obj.keyword())), space(), format(obj.get_name()), space(), colon(), space(), pp(obj.get_type(), opts)};
|
||||||
}
|
}
|
||||||
|
|
||||||
format pp_definition(object const & obj) {
|
format pp_definition(object const & obj, options const & opts) {
|
||||||
return pp_compact_definition(obj.keyword(), obj.get_name(), obj.get_type(), obj.get_value());
|
return pp_compact_definition(obj.keyword(), obj.get_name(), obj.get_type(), obj.get_value(), opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
format pp_notation_decl(object const & obj) {
|
format pp_notation_decl(object const & obj, options const & opts) {
|
||||||
notation_declaration const & n = *(static_cast<notation_declaration const *>(obj.cell()));
|
notation_declaration const & n = *(static_cast<notation_declaration const *>(obj.cell()));
|
||||||
return format{::lean::pp(n.get_op()), space(), colon(), space(), pp(n.get_expr())};
|
return format{::lean::pp(n.get_op()), space(), colon(), space(), pp(n.get_expr(), opts)};
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pp_formatter_cell(frontend const & fe, options const & opts):
|
pp_formatter_cell(frontend const & fe):
|
||||||
m_frontend(fe),
|
m_frontend(fe) {
|
||||||
m_options(opts) {
|
|
||||||
m_indent = get_pp_indent(opts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~pp_formatter_cell() {
|
virtual ~pp_formatter_cell() {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual format operator()(expr const & e) {
|
virtual format operator()(expr const & e, options const & opts) {
|
||||||
return pp(e);
|
return pp(e, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual format operator()(context const & c) {
|
virtual format operator()(context const & c, options const & opts) {
|
||||||
return pp(c, Type(), false);
|
return pp(c, Type(), false, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual format operator()(context const & c, expr const & e, bool format_ctx) {
|
virtual format operator()(context const & c, expr const & e, bool format_ctx, options const & opts) {
|
||||||
if (format_ctx) {
|
if (format_ctx) {
|
||||||
return pp(c, e, true);
|
return pp(c, e, true, opts);
|
||||||
} else {
|
} else {
|
||||||
expr c2 = context_to_lambda(c, e);
|
expr c2 = context_to_lambda(c, e);
|
||||||
while (is_fake_context(c2)) {
|
while (is_fake_context(c2)) {
|
||||||
|
@ -898,20 +897,20 @@ public:
|
||||||
name n1 = get_unused_name(rest);
|
name n1 = get_unused_name(rest);
|
||||||
c2 = instantiate_with_closed(rest, mk_constant(n1));
|
c2 = instantiate_with_closed(rest, mk_constant(n1));
|
||||||
}
|
}
|
||||||
return pp(c2);
|
return pp(c2, opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual format operator()(object const & obj) {
|
virtual format operator()(object const & obj, options const & opts) {
|
||||||
switch (obj.kind()) {
|
switch (obj.kind()) {
|
||||||
case object_kind::UVarDeclaration: return pp_uvar_decl(obj);
|
case object_kind::UVarDeclaration: return pp_uvar_decl(obj, opts);
|
||||||
case object_kind::Postulate: return pp_postulate(obj);
|
case object_kind::Postulate: return pp_postulate(obj, opts);
|
||||||
case object_kind::Definition: return pp_definition(obj);
|
case object_kind::Definition: return pp_definition(obj, opts);
|
||||||
case object_kind::Neutral:
|
case object_kind::Neutral:
|
||||||
if (dynamic_cast<notation_declaration const *>(obj.cell())) {
|
if (dynamic_cast<notation_declaration const *>(obj.cell())) {
|
||||||
// If the object is not notation, then the object was
|
// If the object is not notation, then the object was
|
||||||
// created in different frontend, and we ignore it.
|
// created in different frontend, and we ignore it.
|
||||||
return pp_notation_decl(obj);
|
return pp_notation_decl(obj, opts);
|
||||||
} else {
|
} else {
|
||||||
return format("Unknown neutral object");
|
return format("Unknown neutral object");
|
||||||
}
|
}
|
||||||
|
@ -920,25 +919,25 @@ public:
|
||||||
return format();
|
return format();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual format operator()(environment const & env) {
|
virtual format operator()(environment const & env, options const & opts) {
|
||||||
format r;
|
format r;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
std::for_each(env.begin_objects(),
|
std::for_each(env.begin_objects(),
|
||||||
env.end_objects(),
|
env.end_objects(),
|
||||||
[&](object const & obj) {
|
[&](object const & obj) {
|
||||||
if (first) first = false; else r += line();
|
if (first) first = false; else r += line();
|
||||||
r += operator()(obj);
|
r += operator()(obj, opts);
|
||||||
});
|
});
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
formatter mk_pp_formatter(frontend const & fe, options const & opts) {
|
formatter mk_pp_formatter(frontend const & fe) {
|
||||||
return formatter(new pp_formatter_cell(fe, opts));
|
return formatter(new pp_formatter_cell(fe));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & out, frontend const & fe) {
|
std::ostream & operator<<(std::ostream & out, frontend const & fe) {
|
||||||
formatter fmt = mk_pp_formatter(fe, options());
|
formatter fmt = mk_pp_formatter(fe);
|
||||||
out << fmt(fe.get_environment());
|
out << fmt(fe.get_environment());
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,6 @@ Author: Leonardo de Moura
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
class frontend;
|
class frontend;
|
||||||
formatter mk_pp_formatter(frontend const & fe, options const & opts = options());
|
formatter mk_pp_formatter(frontend const & fe);
|
||||||
std::ostream & operator<<(std::ostream & out, frontend const & fe);
|
std::ostream & operator<<(std::ostream & out, frontend const & fe);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ Author: Leonardo de Moura
|
||||||
#include "frontend.h"
|
#include "frontend.h"
|
||||||
#include "printer.h"
|
#include "printer.h"
|
||||||
#include "abstract.h"
|
#include "abstract.h"
|
||||||
|
#include "builtin.h"
|
||||||
#include "pp.h"
|
#include "pp.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
using namespace lean;
|
using namespace lean;
|
||||||
|
@ -36,8 +37,8 @@ static void tst2() {
|
||||||
expr t = Fun({a, Type()}, mk_shared_expr(10));
|
expr t = Fun({a, Type()}, mk_shared_expr(10));
|
||||||
expr g = Const("g");
|
expr g = Const("g");
|
||||||
std::cout << fmt(g(t, t, t)) << std::endl;
|
std::cout << fmt(g(t, t, t)) << std::endl;
|
||||||
formatter fmt2 = mk_pp_formatter(f, options({"pp", "alias_min_weight"}, 100));
|
formatter fmt2 = mk_pp_formatter(f);
|
||||||
std::cout << fmt2(g(t, t, t)) << std::endl;
|
std::cout << fmt2(g(t, t, t), options({"pp", "alias_min_weight"}, 100)) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tst3() {
|
static void tst3() {
|
||||||
|
@ -56,9 +57,18 @@ static void tst3() {
|
||||||
std::cout << fmt(g(d, c, b, t)) << "\n";
|
std::cout << fmt(g(d, c, b, t)) << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tst4() {
|
||||||
|
frontend f;
|
||||||
|
state const & s = f.get_state();
|
||||||
|
regular(s) << And(Const("a"), Const("b")) << "\n";
|
||||||
|
regular(f) << And(Const("a"), Const("b")) << "\n";
|
||||||
|
diagnostic(f) << And(Const("a"), Const("b")) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
tst1();
|
tst1();
|
||||||
tst2();
|
tst2();
|
||||||
tst3();
|
tst3();
|
||||||
|
tst4();
|
||||||
return has_violations() ? 1 : 0;
|
return has_violations() ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
50
src/util/output_channel.h
Normal file
50
src/util/output_channel.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
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 <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace lean {
|
||||||
|
/**
|
||||||
|
\brief Wrapper for std::ostream.
|
||||||
|
The idea is to be able to have an output stream that can be
|
||||||
|
"reassigned".
|
||||||
|
|
||||||
|
std::unique_ptr<output_channel> out;
|
||||||
|
out = new stdout_channel();
|
||||||
|
(*out) << "writting to standard output";
|
||||||
|
out = new stderr_channel();
|
||||||
|
(*out) << "writting to standard input";
|
||||||
|
out = new file_output_channel("file.txt");
|
||||||
|
(*out) << "writting to file";
|
||||||
|
*/
|
||||||
|
class output_channel {
|
||||||
|
public:
|
||||||
|
virtual ~output_channel() {}
|
||||||
|
virtual std::ostream & get_stream() = 0;
|
||||||
|
};
|
||||||
|
class stdout_channel : public output_channel {
|
||||||
|
public:
|
||||||
|
virtual std::ostream & get_stream() { return std::cout; }
|
||||||
|
};
|
||||||
|
class stderr_channel : public output_channel {
|
||||||
|
public:
|
||||||
|
virtual std::ostream & get_stream() { return std::cerr; }
|
||||||
|
};
|
||||||
|
class file_output_channel : public output_channel {
|
||||||
|
std::ofstream m_out;
|
||||||
|
public:
|
||||||
|
file_output_channel(char const * fname):m_out(fname) {}
|
||||||
|
virtual ~file_output_channel() {}
|
||||||
|
virtual std::ostream & get_stream() { return m_out; }
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
output_channel & operator<<(output_channel & out, T const & v) {
|
||||||
|
out.get_stream() << v;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue