diff options
-rw-r--r-- | src/value.cc | 31 | ||||
-rw-r--r-- | src/value.h | 29 |
2 files changed, 57 insertions, 3 deletions
diff --git a/src/value.cc b/src/value.cc index 54798162..ce9b0e6a 100644 --- a/src/value.cc +++ b/src/value.cc @@ -36,6 +36,7 @@ #include "annotate.h" #include "pool.h" #include "unistring.h" // for justify() +#include "op.h" namespace ledger { @@ -115,6 +116,8 @@ value_t::operator bool() const return false; case SCOPE: return as_scope() != NULL; + case EXPR: + return as_expr(); default: break; } @@ -140,6 +143,12 @@ void value_t::set_type(type_t new_type) } } +void value_t::set_expr(const expr_t& val) +{ + set_type(EXPR); + storage->data = new expr_t(val); +} + bool value_t::to_boolean() const { if (is_boolean()) { @@ -1272,6 +1281,8 @@ bool value_t::is_realzero() const case SCOPE: return as_scope() == NULL; + case EXPR: + return ! as_expr(); default: throw_(value_error, _("Cannot determine if %1 is really zero") << label()); @@ -1301,6 +1312,8 @@ bool value_t::is_zero() const case SCOPE: return as_scope() == NULL; + case EXPR: + return ! as_expr(); default: throw_(value_error, _("Cannot determine if %1 is zero") << label()); @@ -1565,6 +1578,7 @@ value_t value_t::strip_annotations(const keep_details_t& what_to_keep) const case STRING: case MASK: case SCOPE: + case EXPR: return *this; case SEQUENCE: { @@ -1673,7 +1687,15 @@ void value_t::print(std::ostream& out, } case SCOPE: - out << "<SCOPE>"; + out << "<#SCOPE>"; + break; + case EXPR: + out << "<#EXPR "; + if (as_expr()) + as_expr().print(out); + else + out << "null"; + out << ">"; break; default: @@ -1743,6 +1765,12 @@ void value_t::dump(std::ostream& out, const bool relaxed) const case SCOPE: out << as_scope(); break; + case EXPR: + if (as_expr()) + as_expr().dump(out); + else + out << "null"; + break; case SEQUENCE: { out << '('; @@ -1855,6 +1883,7 @@ void to_xml(std::ostream& out, const value_t& value) } case value_t::SCOPE: + case value_t::EXPR: default: assert(false); break; diff --git a/src/value.h b/src/value.h index 1c1d8b6c..3252ed65 100644 --- a/src/value.h +++ b/src/value.h @@ -57,6 +57,7 @@ namespace ledger { DECLARE_EXCEPTION(value_error, std::runtime_error); class scope_t; +class expr_t; /** * @class value_t @@ -108,7 +109,8 @@ public: STRING, // a string object MASK, // a regular expression mask SEQUENCE, // a vector of value_t objects - SCOPE // a pointer to a scope + SCOPE, // a pointer to a scope + EXPR // a pointer to a value expression }; private: @@ -135,7 +137,8 @@ private: string, // STRING mask_t, // MASK sequence_t *, // SEQUENCE - scope_t * // SCOPE + scope_t *, // SCOPE + expr_t * // EXPR > data; type_t type; @@ -351,6 +354,10 @@ public: TRACE_CTOR(value_t, "scope_t *"); set_scope(item); } + explicit value_t(const expr_t& item) { + TRACE_CTOR(value_t, "const expr_t&"); + set_expr(item); + } /** * Destructor. This does not do anything, because the intrusive_ptr @@ -723,6 +730,22 @@ public: } /** + * Dealing with expr pointers. + */ + bool is_expr() const { + return is_type(EXPR); + } + expr_t& as_expr_lval() const { + VERIFY(is_expr()); + return *boost::get<expr_t *>(storage->data); + } + const expr_t& as_expr() const { + VERIFY(is_expr()); + return *boost::get<expr_t *>(storage->data); + } + void set_expr(const expr_t& val); + + /** * Data conversion methods. These methods convert a value object to * its underlying type, where possible. If not possible, an * exception is thrown. @@ -908,6 +931,8 @@ public: return _("a sequence"); case SCOPE: return _("a scope"); + case EXPR: + return _("a expr"); default: assert(false); break; |