/* 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 #include "util/name.h" #include "util/sexpr/sexpr.h" #include "util/sexpr/format.h" #include "util/lua.h" #include "util/serializer.h" namespace lean { enum option_kind { BoolOption, IntOption, UnsignedOption, DoubleOption, StringOption, SExprOption }; std::ostream & operator<<(std::ostream & out, option_kind k); /** \brief Configuration options. */ class options { sexpr m_value; options(sexpr const & v):m_value(v) {} public: options() {} options(options const & o):m_value(o.m_value) {} options(options && o):m_value(std::move(o.m_value)) {} template options(name const & n, T const & t) { *this = update(n, t); } ~options() {} options & operator=(options const & o) { m_value = o.m_value; return *this; } bool empty() const; unsigned size() const; bool contains(name const & n) const; bool contains(char const * n) const; unsigned hash() const { return m_value.hash(); } bool get_bool(name const & n, bool default_value = false) const; int get_int(name const & n, int default_value = 0) const; unsigned get_unsigned(name const & n, unsigned default_value = 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 get_sexpr(name const & n, sexpr const & default_value = sexpr()) const; bool get_bool(char const * n, bool default_value = false) const; int get_int(char const * n, int default_value = 0) const; unsigned get_unsigned(char const * n, unsigned default_value = 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 get_sexpr(char const * n, sexpr const & default_value = sexpr()) const; options update(name const & n, sexpr const & v) const; template options update(name const & n, T v) const { return update(n, sexpr(v)); } options update(name const & n, unsigned v) const { return update(n, sexpr(static_cast(v))); } options update(char const * n, sexpr const & v) const { return update(name(n), v); } template options update(char const * n, T v) const { return update(n, sexpr(v)); } template options update_if_undef(name const & n, T v) const { if (contains(n)) return *this; else return update(n, sexpr(v)); } friend bool is_eqp(options const & a, options const & b) { return is_eqp(a.m_value, b.m_value); } /** \brief Combine the options opts1 and opts2. The assignment in opts2 overrides the ones in opts1. */ friend options join(options const & opts1, options const & opts2); /** \brief Return a new set of options based on \c opts by adding the prefix \c prefix. The procedure throws an exception if \c opts contains an options (o, v), s.t. prefix + o is an unknown option in Lean. */ friend options add_prefix(name const & prefix, options const & opts); friend format pp(options const & o); friend std::ostream & operator<<(std::ostream & out, options const & o); friend serializer & operator<<(serializer & s, options const & o) { s << o.m_value; return s; } friend options read_options(deserializer & d); friend bool operator==(options const & a, options const & b) { return a.m_value == b.m_value; } }; bool get_verbose(options const & opts); inline options read_options(deserializer & d) { return options(read_sexpr(d)); } inline deserializer & operator>>(deserializer & d, options & o) { o = read_options(d); return d; } template options update(options const & o, name const & n, T const & v) { return o.update(n, sexpr(v)); } inline options operator+(options const & opts1, options const & opts2) { return join(opts1, opts2); } struct mk_option_declaration { mk_option_declaration(name const & n, option_kind k, char const * default_value, char const * description); }; int mk_options(name const & prefix, lua_State * L); UDATA_DEFS(options) int options_update(lua_State * L); /** \brief Return the set of options associated with the given Lua State. This procedure checks for options at: 1- Lean state object associated with \c L 2- Lua Registry associated with \c L */ options get_global_options(lua_State * L); /** \brief Update the set of options associated with the given Lua State. If \c L is associated with a Lean state object \c S, then we update the options of \c S. Otherwise, we update the registry of \c L. */ void set_global_options(lua_State * L, options const & o); void open_options(lua_State * L); void initialize_options(); void finalize_options(); }