Add pretty printer for s-expressions and options
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
33e8e4af23
commit
e5fe016a44
9 changed files with 214 additions and 24 deletions
|
@ -17,8 +17,20 @@ static void tst1() {
|
||||||
std::cout << opt << "\n";
|
std::cout << opt << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tst2() {
|
||||||
|
options opt;
|
||||||
|
opt = update(opt, name{"test", "foo"}, 10);
|
||||||
|
opt = update(opt, name{"color"}, 20);
|
||||||
|
opt = update(opt, name{"ratio"}, 10.5);
|
||||||
|
sexpr s{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
|
opt = update(opt, name{"sp", "order"}, sexpr{s, s, s, s, s, s});
|
||||||
|
opt = update(opt, name{"test", "long", "names", "with", "several", "parts"}, true);
|
||||||
|
std::cout << pp(opt) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
continue_on_violation(true);
|
continue_on_violation(true);
|
||||||
tst1();
|
tst1();
|
||||||
|
tst2();
|
||||||
return has_violations() ? 1 : 0;
|
return has_violations() ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ Author: Leonardo de Moura
|
||||||
#include "mpq.h"
|
#include "mpq.h"
|
||||||
#include "name.h"
|
#include "name.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
#include "format.h"
|
||||||
|
#include "options.h"
|
||||||
using namespace lean;
|
using namespace lean;
|
||||||
|
|
||||||
static void tst1() {
|
static void tst1() {
|
||||||
|
@ -116,7 +118,7 @@ static void tst2() {
|
||||||
|
|
||||||
static void tst3() {
|
static void tst3() {
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
foreach(sexpr{0, 1, 2, 3, 4},
|
for_each(sexpr{0, 1, 2, 3, 4},
|
||||||
[&](sexpr const & e) { sum += to_int(e); });
|
[&](sexpr const & e) { sum += to_int(e); });
|
||||||
lean_assert(sum == 10);
|
lean_assert(sum == 10);
|
||||||
}
|
}
|
||||||
|
@ -162,6 +164,13 @@ static void tst6() {
|
||||||
lean_assert(s.str() == "\"str with \\\"quote\\\"\"");
|
lean_assert(s.str() == "\"str with \\\"quote\\\"\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tst7() {
|
||||||
|
sexpr s = sexpr{ sexpr(1,2), sexpr(2,3), sexpr(0,1) };
|
||||||
|
std::cout << pp(sexpr{s, s, s, s, s}) << "\n";
|
||||||
|
std::cout << pp(sexpr{sexpr(name{"test","name"}), sexpr(10), sexpr(10.20)}) << "\n";
|
||||||
|
std::cout << pp(sexpr{sexpr(name{"test","name"}), sexpr(10), sexpr(10.20)}, options(name{"name","separator"}, "-->")) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
continue_on_violation(true);
|
continue_on_violation(true);
|
||||||
tst1();
|
tst1();
|
||||||
|
@ -170,5 +179,6 @@ int main() {
|
||||||
tst4();
|
tst4();
|
||||||
tst5();
|
tst5();
|
||||||
tst6();
|
tst6();
|
||||||
|
tst7();
|
||||||
return has_violations() ? 1 : 0;
|
return has_violations() ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,23 @@
|
||||||
|
|
||||||
Author: Soonho Kong
|
Author: Soonho Kong
|
||||||
*/
|
*/
|
||||||
|
#include <sstream>
|
||||||
#include "sexpr.h"
|
#include "sexpr.h"
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
#include "escaped.h"
|
||||||
#include "sexpr_funcs.h"
|
#include "sexpr_funcs.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
#ifndef LEAN_DEFAULT_INDENTATION
|
||||||
|
#define LEAN_DEFAULT_INDENTATION 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LEAN_DEFAULT_WIDTH
|
||||||
|
#define LEAN_DEFAULT_WIDTH 120
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
static int default_width = 78;
|
static int default_width = LEAN_DEFAULT_WIDTH;
|
||||||
std::ostream & layout(std::ostream & out, sexpr const & s) {
|
std::ostream & layout(std::ostream & out, sexpr const & s) {
|
||||||
lean_assert(!is_nil(s));
|
lean_assert(!is_nil(s));
|
||||||
switch (format::sexpr_kind(s)) {
|
switch (format::sexpr_kind(s)) {
|
||||||
|
@ -53,7 +64,7 @@ std::ostream & layout(std::ostream & out, sexpr const & s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream & layout_list(std::ostream & out, sexpr const & s) {
|
std::ostream & layout_list(std::ostream & out, sexpr const & s) {
|
||||||
foreach(s, [&out](sexpr const & s) {
|
for_each(s, [&out](sexpr const & s) {
|
||||||
layout(out, s);
|
layout(out, s);
|
||||||
});
|
});
|
||||||
return out;
|
return out;
|
||||||
|
@ -68,10 +79,35 @@ format nest(int i, format const & f) {
|
||||||
format highlight(format const & f, format::format_color const c) {
|
format highlight(format const & f, format::format_color const c) {
|
||||||
return format(format::sexpr_highlight(f.m_value, c));
|
return format(format::sexpr_highlight(f.m_value, c));
|
||||||
}
|
}
|
||||||
format line() {
|
// Commonly used format objects
|
||||||
|
format mk_line() {
|
||||||
return format(format::sexpr_line());
|
return format(format::sexpr_line());
|
||||||
}
|
}
|
||||||
|
static format g_line(mk_line());
|
||||||
|
static format g_space(" ");
|
||||||
|
static format g_lp("(");
|
||||||
|
static format g_rp(")");
|
||||||
|
static format g_comma(",");
|
||||||
|
static format g_dot(".");
|
||||||
|
format const & line() {
|
||||||
|
return g_line;
|
||||||
|
}
|
||||||
|
format const & space() {
|
||||||
|
return g_space;
|
||||||
|
}
|
||||||
|
format const & lp() {
|
||||||
|
return g_lp;
|
||||||
|
}
|
||||||
|
format const & rp() {
|
||||||
|
return g_rp;
|
||||||
|
}
|
||||||
|
format const & comma() {
|
||||||
|
return g_comma;
|
||||||
|
}
|
||||||
|
format const & dot() {
|
||||||
|
return g_dot;
|
||||||
|
}
|
||||||
|
//
|
||||||
sexpr format::flatten(sexpr const & s) {
|
sexpr format::flatten(sexpr const & s) {
|
||||||
lean_assert(is_cons(s));
|
lean_assert(is_cons(s));
|
||||||
switch (sexpr_kind(s)) {
|
switch (sexpr_kind(s)) {
|
||||||
|
@ -243,8 +279,7 @@ sexpr format::best(unsigned w, unsigned k, sexpr const & s) {
|
||||||
return be(w, k, sexpr{sexpr(0, s)});
|
return be(w, k, sexpr{sexpr(0, s)});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & out, format const & f)
|
std::ostream & operator<<(std::ostream & out, format const & f) {
|
||||||
{
|
|
||||||
return pretty(out, default_width, f);
|
return pretty(out, default_width, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,4 +295,73 @@ std::ostream & pretty(std::ostream & out, unsigned w, format const & f) {
|
||||||
sexpr const & b = format::best(w, 0, f.m_value);
|
sexpr const & b = format::best(w, 0, f.m_value);
|
||||||
return layout_list(out, b);
|
return layout_list(out, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static name g_pp_indent{"pp", "indent"};
|
||||||
|
|
||||||
|
unsigned get_pp_indent(options const & o) {
|
||||||
|
return o.get_int(g_pp_indent, LEAN_DEFAULT_INDENTATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
format pp(name const & n, char const * sep) {
|
||||||
|
return format(n.to_string(sep));
|
||||||
|
}
|
||||||
|
|
||||||
|
format pp(name const & n, options const & o) {
|
||||||
|
return pp(n, get_name_separator(o));
|
||||||
|
}
|
||||||
|
|
||||||
|
format pp(name const & n) {
|
||||||
|
return pp(n, get_name_separator(options()));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sexpr_pp_fn {
|
||||||
|
char const * m_sep;
|
||||||
|
|
||||||
|
format apply(sexpr const & s) {
|
||||||
|
switch (s.kind()) {
|
||||||
|
case sexpr_kind::NIL: return format("nil");
|
||||||
|
case sexpr_kind::STRING: {
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "\"" << escaped(to_string(s).c_str()) << "\"";
|
||||||
|
return format(ss.str());
|
||||||
|
}
|
||||||
|
case sexpr_kind::BOOL: return format(to_bool(s) ? "true" : "false");
|
||||||
|
case sexpr_kind::INT: return format(to_int(s));
|
||||||
|
case sexpr_kind::DOUBLE: return format(to_double(s));
|
||||||
|
case sexpr_kind::NAME: return pp(to_name(s), m_sep);
|
||||||
|
case sexpr_kind::MPZ: return format(to_mpz(s));
|
||||||
|
case sexpr_kind::MPQ: return format(to_mpq(s));
|
||||||
|
case sexpr_kind::CONS: {
|
||||||
|
sexpr const * curr = &s;
|
||||||
|
format r;
|
||||||
|
while (true) {
|
||||||
|
r += apply(head(*curr));
|
||||||
|
curr = &tail(*curr);
|
||||||
|
if (is_nil(*curr)) {
|
||||||
|
return group(nest(1, format{lp(), r, rp()}));
|
||||||
|
} else if (!is_cons(*curr)) {
|
||||||
|
return group(nest(1, format{lp(), r, space(), dot(), line(), apply(*curr), rp()}));
|
||||||
|
} else {
|
||||||
|
r += line();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
lean_unreachable();
|
||||||
|
return format();
|
||||||
|
}
|
||||||
|
|
||||||
|
format operator()(sexpr const & s, options const & o) {
|
||||||
|
m_sep = get_name_separator(o);
|
||||||
|
return apply(s);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
format pp(sexpr const & s, options const & o) {
|
||||||
|
return sexpr_pp_fn()(s, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
format pp(sexpr const & s) {
|
||||||
|
return pp(s, options());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,7 +177,7 @@ public:
|
||||||
friend format compose(format const & f1, format const & f2);
|
friend format compose(format const & f1, format const & f2);
|
||||||
friend format nest(int i, format const & f);
|
friend format nest(int i, format const & f);
|
||||||
friend format highlight(format const & f, format::format_color const c = RED);
|
friend format highlight(format const & f, format::format_color const c = RED);
|
||||||
friend format line();
|
friend format mk_line();
|
||||||
|
|
||||||
friend format group(format const & f);
|
friend format group(format const & f);
|
||||||
friend format above(format const & f1, format const & f2);
|
friend format above(format const & f1, format const & f2);
|
||||||
|
@ -208,7 +208,12 @@ format wrap(format const & f1, format const & f2);
|
||||||
format compose(format const & f1, format const & f2);
|
format compose(format const & f1, format const & f2);
|
||||||
format nest(int i, format const & f);
|
format nest(int i, format const & f);
|
||||||
format highlight(format const & f, format::format_color const c);
|
format highlight(format const & f, format::format_color const c);
|
||||||
format line();
|
format const & line();
|
||||||
|
format const & space();
|
||||||
|
format const & lp();
|
||||||
|
format const & rp();
|
||||||
|
format const & comma();
|
||||||
|
format const & dot();
|
||||||
format group(format const & f);
|
format group(format const & f);
|
||||||
format above(format const & f1, format const & f2);
|
format above(format const & f1, format const & f2);
|
||||||
format bracket(std::string const l, format const & x, std::string const r);
|
format bracket(std::string const l, format const & x, std::string const r);
|
||||||
|
@ -275,4 +280,16 @@ format fillwords(InputIterator first, InputIterator last) {
|
||||||
inline format fillwords(std::initializer_list<std::string> const & l) {
|
inline format fillwords(std::initializer_list<std::string> const & l) {
|
||||||
return fillwords(l.begin(), l.end());
|
return fillwords(l.begin(), l.end());
|
||||||
}
|
}
|
||||||
|
class options;
|
||||||
|
/** \brief Extract indentation from options */
|
||||||
|
unsigned get_pp_indent(options const & o);
|
||||||
|
|
||||||
|
/** \brief Format a hierarchical name */
|
||||||
|
format pp(name const & n, char const * s);
|
||||||
|
format pp(name const & n, options const & o);
|
||||||
|
format pp(name const & n);
|
||||||
|
|
||||||
|
/** \brief Format a S-expression */
|
||||||
|
format pp(sexpr const & s, options const & o);
|
||||||
|
format pp(sexpr const & s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,11 @@ Author: Leonardo de Moura
|
||||||
#include "rc.h"
|
#include "rc.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
#ifndef LEAN_DEFAULT_NAME_SEPARATOR
|
||||||
|
#define LEAN_DEFAULT_NAME_SEPARATOR "::"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
|
||||||
|
@ -263,6 +268,10 @@ size_t name::size(char const * sep) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t name::size() const {
|
||||||
|
return size(LEAN_DEFAULT_NAME_SEPARATOR);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned name::hash() const {
|
unsigned name::hash() const {
|
||||||
return m_ptr ? m_ptr->m_hash : 11;
|
return m_ptr ? m_ptr->m_hash : 11;
|
||||||
}
|
}
|
||||||
|
@ -273,8 +282,12 @@ std::string name::to_string(char const * sep) const {
|
||||||
return s.str();
|
return s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string name::to_string() const {
|
||||||
|
return to_string(LEAN_DEFAULT_NAME_SEPARATOR);
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & out, name const & n) {
|
std::ostream & operator<<(std::ostream & out, name const & n) {
|
||||||
name::imp::display(out, default_name_separator, n.m_ptr);
|
name::imp::display(out, LEAN_DEFAULT_NAME_SEPARATOR, n.m_ptr);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +297,12 @@ std::ostream & operator<<(std::ostream & out, name::sep const & s) {
|
||||||
name::imp::display(out, s.m_sep, s.m_name.m_ptr);
|
name::imp::display(out, s.m_sep, s.m_name.m_ptr);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static name g_name_separator{"name", "separator"};
|
||||||
|
|
||||||
|
char const * get_name_separator(options const & o) {
|
||||||
|
return o.get_string(g_name_separator, LEAN_DEFAULT_NAME_SEPARATOR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(lean::name const & n) { std::cout << n << std::endl; }
|
void print(lean::name const & n) { std::cout << n << std::endl; }
|
||||||
|
|
|
@ -9,7 +9,7 @@ Author: Leonardo de Moura
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
|
||||||
constexpr char const * default_name_separator = "\u2055";
|
constexpr char const * default_name_separator = "::";
|
||||||
enum class name_kind { ANONYMOUS, STRING, NUMERAL };
|
enum class name_kind { ANONYMOUS, STRING, NUMERAL };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,11 +53,13 @@ public:
|
||||||
/**
|
/**
|
||||||
\brief Convert this hierarchical name into a string using the given separator to "glue" the different limbs.
|
\brief Convert this hierarchical name into a string using the given separator to "glue" the different limbs.
|
||||||
*/
|
*/
|
||||||
std::string to_string(char const * sep = default_name_separator) const;
|
std::string to_string(char const * sep) const;
|
||||||
|
std::string to_string() const;
|
||||||
/**
|
/**
|
||||||
\brief Size of the this name (in characters) when using the given separator.
|
\brief Size of the this name (in characters) when using the given separator.
|
||||||
*/
|
*/
|
||||||
size_t size(char const * sep = default_name_separator) const;
|
size_t size(char const * sep) const;
|
||||||
|
size_t size() const;
|
||||||
unsigned hash() const;
|
unsigned hash() const;
|
||||||
friend std::ostream & operator<<(std::ostream & out, name const & n);
|
friend std::ostream & operator<<(std::ostream & out, name const & n);
|
||||||
class sep {
|
class sep {
|
||||||
|
@ -71,4 +73,8 @@ public:
|
||||||
};
|
};
|
||||||
struct name_hash { unsigned operator()(name const & n) const { return n.hash(); } };
|
struct name_hash { unsigned operator()(name const & n) const { return n.hash(); } };
|
||||||
struct name_eq { bool operator()(name const & n1, name const & n2) const { return n1 == n2; } };
|
struct name_eq { bool operator()(name const & n1, name const & n2) const { return n1 == n2; } };
|
||||||
|
|
||||||
|
class options;
|
||||||
|
/** \brief Return the separator for hierarchical names */
|
||||||
|
char const * get_name_separator(options const & o);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ bool options::contains(char const * n) const {
|
||||||
|
|
||||||
sexpr const & options::get_sexpr(name const & n, sexpr const & default_value) const {
|
sexpr const & options::get_sexpr(name const & n, sexpr const & default_value) const {
|
||||||
sexpr const * r = find(m_value, [&](sexpr const & p) { return to_name(head(p)) == n; });
|
sexpr const * r = find(m_value, [&](sexpr const & p) { return to_name(head(p)) == n; });
|
||||||
return r == nullptr ? default_value : *r;
|
return r == nullptr ? default_value : tail(*r);
|
||||||
}
|
}
|
||||||
|
|
||||||
int options::get_int(name const & n, int default_value) const {
|
int options::get_int(name const & n, int default_value) const {
|
||||||
|
@ -45,6 +45,11 @@ double options::get_double(name const & n, double default_value) const {
|
||||||
return !is_nil(r) && is_double(r) ? to_double(r) : default_value;
|
return !is_nil(r) && is_double(r) ? to_double(r) : default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char const * options::get_string(name const & n, char const * default_value) const {
|
||||||
|
sexpr const & r = get_sexpr(n);
|
||||||
|
return !is_nil(r) && is_string(r) ? to_string(r).c_str() : default_value;
|
||||||
|
}
|
||||||
|
|
||||||
sexpr const & options::get_sexpr(char const * n, sexpr const & default_value) const {
|
sexpr const & options::get_sexpr(char const * n, sexpr const & default_value) const {
|
||||||
sexpr const * r = find(m_value, [&](sexpr const & p) { return to_name(head(p)) == n; });
|
sexpr const * r = find(m_value, [&](sexpr const & p) { return to_name(head(p)) == n; });
|
||||||
return r == nullptr ? default_value : *r;
|
return r == nullptr ? default_value : *r;
|
||||||
|
@ -65,27 +70,40 @@ double options::get_double(char const * n, double default_value) const {
|
||||||
return !is_nil(r) && is_double(r) ? to_double(r) : default_value;
|
return !is_nil(r) && is_double(r) ? to_double(r) : default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr char const * left_angle_bracket = "\u27E8";
|
char const * options::get_string(char const * n, char const * default_value) const {
|
||||||
constexpr char const * right_angle_bracket = "\u27E9";
|
sexpr const & r = get_sexpr(n);
|
||||||
constexpr char const * arrow = "\u21a6";
|
return !is_nil(r) && is_string(r) ? to_string(r).c_str() : default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char const * g_left_angle_bracket = "\u27E8";
|
||||||
|
static char const * g_right_angle_bracket = "\u27E9";
|
||||||
|
static char const * g_arrow = "\u21a6";
|
||||||
|
|
||||||
options options::update(name const & n, sexpr const & v) const {
|
options options::update(name const & n, sexpr const & v) const {
|
||||||
return options(cons(cons(sexpr(n), v), m_value));
|
return options(cons(cons(sexpr(n), v), m_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
format pp(options const & o) {
|
format pp(options const & o) {
|
||||||
// TODO
|
char const * sep = get_name_separator(o);
|
||||||
return format();
|
format r;
|
||||||
|
bool first = true;
|
||||||
|
for_each(o.m_value, [&](sexpr const & p) {
|
||||||
|
if (first) { first = false; } else { r += comma(); r += line(); }
|
||||||
|
name const & n = to_name(head(p));
|
||||||
|
unsigned sz = n.size(sep);
|
||||||
|
r += group(nest(sz+3, format{pp(head(p), o), space(), format(g_arrow), space(), pp(tail(p), o)}));
|
||||||
|
});
|
||||||
|
return group(nest(1, format{format(g_left_angle_bracket), r, format(g_right_angle_bracket)}));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & out, options const & o) {
|
std::ostream & operator<<(std::ostream & out, options const & o) {
|
||||||
out << left_angle_bracket;
|
out << g_left_angle_bracket;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
foreach(o.m_value, [&](sexpr const & p) {
|
for_each(o.m_value, [&](sexpr const & p) {
|
||||||
if (first) first = false; else out << ", ";
|
if (first) first = false; else out << ", ";
|
||||||
out << head(p) << " " << arrow << " " << tail(p);
|
out << head(p) << " " << g_arrow << " " << tail(p);
|
||||||
});
|
});
|
||||||
out << right_angle_bracket;
|
out << g_right_angle_bracket;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
Author: Leonardo de Moura
|
Author: Leonardo de Moura
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <algorithm>
|
||||||
#include "sexpr.h"
|
#include "sexpr.h"
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
#include "name.h"
|
#include "name.h"
|
||||||
|
@ -18,6 +19,7 @@ public:
|
||||||
options() {}
|
options() {}
|
||||||
options(options const & o):m_value(o.m_value) {}
|
options(options const & o):m_value(o.m_value) {}
|
||||||
options(options && o):m_value(std::move(o.m_value)) {}
|
options(options && o):m_value(std::move(o.m_value)) {}
|
||||||
|
template<typename T> options(name const & n, T const & t) { *this = update(n, t); }
|
||||||
~options() {}
|
~options() {}
|
||||||
|
|
||||||
options & operator=(options const & o) { m_value = o.m_value; return *this; }
|
options & operator=(options const & o) { m_value = o.m_value; return *this; }
|
||||||
|
@ -30,11 +32,13 @@ public:
|
||||||
bool get_bool(name const & n, bool default_value=false) const;
|
bool get_bool(name const & n, bool default_value=false) const;
|
||||||
int get_int(name const & n, int default_value=0) const;
|
int get_int(name const & n, int default_value=0) const;
|
||||||
double get_double(name const & n, double default_value=0.0) const;
|
double get_double(name const & n, double default_value=0.0) const;
|
||||||
|
char const * get_string(name const & n, char const * default_value=nullptr) const;
|
||||||
sexpr const & get_sexpr(name const & n, sexpr const & default_value=sexpr()) const;
|
sexpr const & get_sexpr(name const & n, sexpr const & default_value=sexpr()) const;
|
||||||
|
|
||||||
bool get_bool(char const * n, bool default_value=false) const;
|
bool get_bool(char const * n, bool default_value=false) const;
|
||||||
int get_int(char const * n, int default_value=0) const;
|
int get_int(char const * n, int default_value=0) const;
|
||||||
double get_double(char const * n, double default_value=0.0) const;
|
double get_double(char const * n, double default_value=0.0) const;
|
||||||
|
char const * get_string(char const * n, char const * default_value=nullptr) const;
|
||||||
sexpr const & get_sexpr(char const * n, sexpr const & default_value=sexpr()) const;
|
sexpr const & get_sexpr(char const * n, sexpr const & default_value=sexpr()) const;
|
||||||
|
|
||||||
options update(name const & n, sexpr const & v) const;
|
options update(name const & n, sexpr const & v) const;
|
||||||
|
|
|
@ -11,7 +11,7 @@ Author: Leonardo de Moura
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
void foreach(sexpr const & l, F f) {
|
void for_each(sexpr const & l, F f) {
|
||||||
static_assert(std::is_same<typename std::result_of<F(sexpr const &)>::type, void>::value,
|
static_assert(std::is_same<typename std::result_of<F(sexpr const &)>::type, void>::value,
|
||||||
"foreach: return type of f is not void");
|
"foreach: return type of f is not void");
|
||||||
lean_assert(is_list(l));
|
lean_assert(is_list(l));
|
||||||
|
|
Loading…
Reference in a new issue