Allow expr_t& to be passed in a value_t

This commit is contained in:
John Wiegley 2010-05-08 02:00:35 -04:00
parent 4028f0bcb4
commit 2d28b34ff3
2 changed files with 57 additions and 3 deletions

View file

@ -36,6 +36,7 @@
#include "annotate.h" #include "annotate.h"
#include "pool.h" #include "pool.h"
#include "unistring.h" // for justify() #include "unistring.h" // for justify()
#include "op.h"
namespace ledger { namespace ledger {
@ -115,6 +116,8 @@ value_t::operator bool() const
return false; return false;
case SCOPE: case SCOPE:
return as_scope() != NULL; return as_scope() != NULL;
case EXPR:
return as_expr();
default: default:
break; 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 bool value_t::to_boolean() const
{ {
if (is_boolean()) { if (is_boolean()) {
@ -1272,6 +1281,8 @@ bool value_t::is_realzero() const
case SCOPE: case SCOPE:
return as_scope() == NULL; return as_scope() == NULL;
case EXPR:
return ! as_expr();
default: default:
throw_(value_error, _("Cannot determine if %1 is really zero") << label()); throw_(value_error, _("Cannot determine if %1 is really zero") << label());
@ -1301,6 +1312,8 @@ bool value_t::is_zero() const
case SCOPE: case SCOPE:
return as_scope() == NULL; return as_scope() == NULL;
case EXPR:
return ! as_expr();
default: default:
throw_(value_error, _("Cannot determine if %1 is zero") << label()); 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 STRING:
case MASK: case MASK:
case SCOPE: case SCOPE:
case EXPR:
return *this; return *this;
case SEQUENCE: { case SEQUENCE: {
@ -1673,7 +1687,15 @@ void value_t::print(std::ostream& out,
} }
case SCOPE: case SCOPE:
out << "<SCOPE>"; out << "<#SCOPE>";
break;
case EXPR:
out << "<#EXPR ";
if (as_expr())
as_expr().print(out);
else
out << "null";
out << ">";
break; break;
default: default:
@ -1743,6 +1765,12 @@ void value_t::dump(std::ostream& out, const bool relaxed) const
case SCOPE: case SCOPE:
out << as_scope(); out << as_scope();
break; break;
case EXPR:
if (as_expr())
as_expr().dump(out);
else
out << "null";
break;
case SEQUENCE: { case SEQUENCE: {
out << '('; out << '(';
@ -1855,6 +1883,7 @@ void to_xml(std::ostream& out, const value_t& value)
} }
case value_t::SCOPE: case value_t::SCOPE:
case value_t::EXPR:
default: default:
assert(false); assert(false);
break; break;

View file

@ -57,6 +57,7 @@ namespace ledger {
DECLARE_EXCEPTION(value_error, std::runtime_error); DECLARE_EXCEPTION(value_error, std::runtime_error);
class scope_t; class scope_t;
class expr_t;
/** /**
* @class value_t * @class value_t
@ -108,7 +109,8 @@ public:
STRING, // a string object STRING, // a string object
MASK, // a regular expression mask MASK, // a regular expression mask
SEQUENCE, // a vector of value_t objects 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: private:
@ -135,7 +137,8 @@ private:
string, // STRING string, // STRING
mask_t, // MASK mask_t, // MASK
sequence_t *, // SEQUENCE sequence_t *, // SEQUENCE
scope_t * // SCOPE scope_t *, // SCOPE
expr_t * // EXPR
> data; > data;
type_t type; type_t type;
@ -351,6 +354,10 @@ public:
TRACE_CTOR(value_t, "scope_t *"); TRACE_CTOR(value_t, "scope_t *");
set_scope(item); 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 * Destructor. This does not do anything, because the intrusive_ptr
@ -722,6 +729,22 @@ public:
storage->data = val; storage->data = val;
} }
/**
* 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 * Data conversion methods. These methods convert a value object to
* its underlying type, where possible. If not possible, an * its underlying type, where possible. If not possible, an
@ -908,6 +931,8 @@ public:
return _("a sequence"); return _("a sequence");
case SCOPE: case SCOPE:
return _("a scope"); return _("a scope");
case EXPR:
return _("a expr");
default: default:
assert(false); assert(false);
break; break;