Change the value_t::POINTER type to value_t::SCOPE
scope_t pointers are the only kind that are ever stored in value objects, so there was no need to make it generic and use boost::any.
This commit is contained in:
parent
5f2c766e0d
commit
7ca80112fc
6 changed files with 37 additions and 68 deletions
|
|
@ -118,9 +118,9 @@ void interactive_t::verify_arguments() const
|
|||
label = _("any value");
|
||||
wrong_arg = false;
|
||||
break;
|
||||
case 'P':
|
||||
label = _("a pointer");
|
||||
wrong_arg = ! next_arg->is_pointer();
|
||||
case '^':
|
||||
label = _("a scope");
|
||||
wrong_arg = ! next_arg->is_scope();
|
||||
break;
|
||||
case 'S':
|
||||
label = _("a sequence");
|
||||
|
|
|
|||
|
|
@ -172,12 +172,12 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
|||
left()->left() && left()->left()->is_function()) {
|
||||
call_scope_t call_args(scope);
|
||||
if (value_t obj = left()->left()->as_function()(call_args)) {
|
||||
if (obj.is_pointer()) {
|
||||
if (obj.as_pointer_lval<scope_t>() == NULL) {
|
||||
if (obj.is_scope()) {
|
||||
if (obj.as_scope() == NULL) {
|
||||
throw_(calc_error,
|
||||
_("Left operand of . operator is NULL"));
|
||||
} else {
|
||||
scope_t& objscope(obj.as_ref_lval<scope_t>());
|
||||
scope_t& objscope(*obj.as_scope());
|
||||
if (ptr_op_t member = objscope.lookup(right()->as_ident())) {
|
||||
result = member->calc(objscope, NULL, depth + 1);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(value_overloads, value, 0, 2)
|
|||
namespace {
|
||||
expr_t py_value_getattr(const value_t& value, const string& name)
|
||||
{
|
||||
if (value.is_pointer()) {
|
||||
if (scope_t * scope = value.as_pointer<scope_t>())
|
||||
if (value.is_scope()) {
|
||||
if (scope_t * scope = value.as_scope())
|
||||
return expr_t(scope->lookup(name), scope);
|
||||
}
|
||||
throw_(value_error, _("Cannot lookup attributes in %1") << value.label());
|
||||
|
|
@ -283,7 +283,7 @@ void export_value()
|
|||
.value("BALANCE", value_t::BALANCE)
|
||||
.value("STRING", value_t::STRING)
|
||||
.value("SEQUENCE", value_t::SEQUENCE)
|
||||
.value("POINTER", value_t::POINTER)
|
||||
.value("SCOPE", value_t::SCOPE)
|
||||
;
|
||||
|
||||
scope().attr("NULL_VALUE") = NULL_VALUE;
|
||||
|
|
|
|||
|
|
@ -138,7 +138,6 @@ typedef std::ostream::pos_type ostream_pos_type;
|
|||
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/cast.hpp>
|
||||
#include <boost/current_function.hpp>
|
||||
|
|
|
|||
22
src/value.cc
22
src/value.cc
|
|
@ -113,8 +113,8 @@ value_t::operator bool() const
|
|||
}
|
||||
}
|
||||
return false;
|
||||
case POINTER:
|
||||
return ! as_any_pointer().empty();
|
||||
case SCOPE:
|
||||
return as_scope() != NULL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1206,8 +1206,8 @@ bool value_t::is_realzero() const
|
|||
case SEQUENCE:
|
||||
return as_sequence().empty();
|
||||
|
||||
case POINTER:
|
||||
return as_any_pointer().empty();
|
||||
case SCOPE:
|
||||
return as_scope() == NULL;
|
||||
|
||||
default:
|
||||
throw_(value_error, _("Cannot determine if %1 is really zero") << label());
|
||||
|
|
@ -1235,8 +1235,8 @@ bool value_t::is_zero() const
|
|||
case SEQUENCE:
|
||||
return as_sequence().empty();
|
||||
|
||||
case POINTER:
|
||||
return as_any_pointer().empty();
|
||||
case SCOPE:
|
||||
return as_scope() == NULL;
|
||||
|
||||
default:
|
||||
throw_(value_error, _("Cannot determine if %1 is zero") << label());
|
||||
|
|
@ -1474,7 +1474,7 @@ value_t value_t::strip_annotations(const keep_details_t& what_to_keep) const
|
|||
case DATE:
|
||||
case STRING:
|
||||
case MASK:
|
||||
case POINTER:
|
||||
case SCOPE:
|
||||
return *this;
|
||||
|
||||
case SEQUENCE: {
|
||||
|
|
@ -1579,8 +1579,8 @@ void value_t::print(std::ostream& out,
|
|||
break;
|
||||
}
|
||||
|
||||
case POINTER:
|
||||
out << "<POINTER>";
|
||||
case SCOPE:
|
||||
out << "<SCOPE>";
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -1647,8 +1647,8 @@ void value_t::dump(std::ostream& out, const bool relaxed) const
|
|||
out << '/' << as_mask() << '/';
|
||||
break;
|
||||
|
||||
case POINTER:
|
||||
out << boost::unsafe_any_cast<const void *>(&as_any_pointer());
|
||||
case SCOPE:
|
||||
out << as_scope();
|
||||
break;
|
||||
|
||||
case SEQUENCE: {
|
||||
|
|
|
|||
64
src/value.h
64
src/value.h
|
|
@ -56,6 +56,8 @@ namespace ledger {
|
|||
|
||||
DECLARE_EXCEPTION(value_error, std::runtime_error);
|
||||
|
||||
class scope_t;
|
||||
|
||||
/**
|
||||
* @class value_t
|
||||
*
|
||||
|
|
@ -107,7 +109,7 @@ public:
|
|||
STRING, // a string object
|
||||
MASK, // a regular expression mask
|
||||
SEQUENCE, // a vector of value_t objects
|
||||
POINTER // an opaque pointer of any type
|
||||
SCOPE // a pointer to a scope
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
@ -134,7 +136,7 @@ private:
|
|||
string, // STRING
|
||||
mask_t, // MASK
|
||||
sequence_t *, // SEQUENCE
|
||||
boost::any // POINTER
|
||||
scope_t * // SCOPE
|
||||
> data;
|
||||
|
||||
type_t type;
|
||||
|
|
@ -332,10 +334,9 @@ public:
|
|||
set_sequence(val);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
explicit value_t(T * item) {
|
||||
TRACE_CTOR(value_t, "T *");
|
||||
set_pointer(item);
|
||||
explicit value_t(scope_t * item) {
|
||||
TRACE_CTOR(value_t, "scope_t *");
|
||||
set_scope(item);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -687,50 +688,19 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* Dealing with pointers is bit involved because we actually deal
|
||||
* with typed pointers. For example, if you call as_pointer it
|
||||
* returns a boost::any object, but if you use as_pointer<void>,
|
||||
* then it returns a void *. The latter form only succeeds if the
|
||||
* stored pointers was assigned to the value as a void*, otherwise
|
||||
* it throws an exception.
|
||||
* Dealing with scope pointers.
|
||||
*/
|
||||
bool is_pointer() const {
|
||||
return is_type(POINTER);
|
||||
bool is_scope() const {
|
||||
return is_type(SCOPE);
|
||||
}
|
||||
boost::any& as_any_pointer_lval() {
|
||||
VERIFY(is_pointer());
|
||||
_dup();
|
||||
return boost::get<boost::any>(storage->data);
|
||||
scope_t * as_scope() const {
|
||||
VERIFY(is_scope());
|
||||
return boost::get<scope_t *>(storage->data);
|
||||
}
|
||||
template <typename T>
|
||||
T * as_pointer_lval() {
|
||||
return any_cast<T *>(as_any_pointer_lval());
|
||||
}
|
||||
template <typename T>
|
||||
T& as_ref_lval() {
|
||||
return *as_pointer_lval<T>();
|
||||
}
|
||||
const boost::any& as_any_pointer() const {
|
||||
VERIFY(is_pointer());
|
||||
return boost::get<boost::any>(storage->data);
|
||||
}
|
||||
template <typename T>
|
||||
T * as_pointer() const {
|
||||
return any_cast<T *>(as_any_pointer());
|
||||
}
|
||||
template <typename T>
|
||||
T& as_ref() const {
|
||||
return *as_pointer<T>();
|
||||
}
|
||||
void set_any_pointer(const boost::any& val) {
|
||||
set_type(POINTER);
|
||||
void set_scope(scope_t * val) {
|
||||
set_type(SCOPE);
|
||||
storage->data = val;
|
||||
}
|
||||
template <typename T>
|
||||
void set_pointer(T * val) {
|
||||
set_type(POINTER);
|
||||
storage->data = boost::any(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data conversion methods. These methods convert a value object to
|
||||
|
|
@ -902,8 +872,8 @@ public:
|
|||
return _("a regexp");
|
||||
case SEQUENCE:
|
||||
return _("a sequence");
|
||||
case POINTER:
|
||||
return _("a pointer");
|
||||
case SCOPE:
|
||||
return _("a scope");
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue