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");
|
label = _("any value");
|
||||||
wrong_arg = false;
|
wrong_arg = false;
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case '^':
|
||||||
label = _("a pointer");
|
label = _("a scope");
|
||||||
wrong_arg = ! next_arg->is_pointer();
|
wrong_arg = ! next_arg->is_scope();
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
label = _("a sequence");
|
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()) {
|
left()->left() && left()->left()->is_function()) {
|
||||||
call_scope_t call_args(scope);
|
call_scope_t call_args(scope);
|
||||||
if (value_t obj = left()->left()->as_function()(call_args)) {
|
if (value_t obj = left()->left()->as_function()(call_args)) {
|
||||||
if (obj.is_pointer()) {
|
if (obj.is_scope()) {
|
||||||
if (obj.as_pointer_lval<scope_t>() == NULL) {
|
if (obj.as_scope() == NULL) {
|
||||||
throw_(calc_error,
|
throw_(calc_error,
|
||||||
_("Left operand of . operator is NULL"));
|
_("Left operand of . operator is NULL"));
|
||||||
} else {
|
} 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())) {
|
if (ptr_op_t member = objscope.lookup(right()->as_ident())) {
|
||||||
result = member->calc(objscope, NULL, depth + 1);
|
result = member->calc(objscope, NULL, depth + 1);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(value_overloads, value, 0, 2)
|
||||||
namespace {
|
namespace {
|
||||||
expr_t py_value_getattr(const value_t& value, const string& name)
|
expr_t py_value_getattr(const value_t& value, const string& name)
|
||||||
{
|
{
|
||||||
if (value.is_pointer()) {
|
if (value.is_scope()) {
|
||||||
if (scope_t * scope = value.as_pointer<scope_t>())
|
if (scope_t * scope = value.as_scope())
|
||||||
return expr_t(scope->lookup(name), scope);
|
return expr_t(scope->lookup(name), scope);
|
||||||
}
|
}
|
||||||
throw_(value_error, _("Cannot lookup attributes in %1") << value.label());
|
throw_(value_error, _("Cannot lookup attributes in %1") << value.label());
|
||||||
|
|
@ -283,7 +283,7 @@ void export_value()
|
||||||
.value("BALANCE", value_t::BALANCE)
|
.value("BALANCE", value_t::BALANCE)
|
||||||
.value("STRING", value_t::STRING)
|
.value("STRING", value_t::STRING)
|
||||||
.value("SEQUENCE", value_t::SEQUENCE)
|
.value("SEQUENCE", value_t::SEQUENCE)
|
||||||
.value("POINTER", value_t::POINTER)
|
.value("SCOPE", value_t::SCOPE)
|
||||||
;
|
;
|
||||||
|
|
||||||
scope().attr("NULL_VALUE") = NULL_VALUE;
|
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/classification.hpp>
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/any.hpp>
|
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/cast.hpp>
|
#include <boost/cast.hpp>
|
||||||
#include <boost/current_function.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;
|
return false;
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
return ! as_any_pointer().empty();
|
return as_scope() != NULL;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1206,8 +1206,8 @@ bool value_t::is_realzero() const
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
return as_sequence().empty();
|
return as_sequence().empty();
|
||||||
|
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
return as_any_pointer().empty();
|
return as_scope() == NULL;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw_(value_error, _("Cannot determine if %1 is really zero") << label());
|
throw_(value_error, _("Cannot determine if %1 is really zero") << label());
|
||||||
|
|
@ -1235,8 +1235,8 @@ bool value_t::is_zero() const
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
return as_sequence().empty();
|
return as_sequence().empty();
|
||||||
|
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
return as_any_pointer().empty();
|
return as_scope() == NULL;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw_(value_error, _("Cannot determine if %1 is zero") << label());
|
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 DATE:
|
||||||
case STRING:
|
case STRING:
|
||||||
case MASK:
|
case MASK:
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
case SEQUENCE: {
|
case SEQUENCE: {
|
||||||
|
|
@ -1579,8 +1579,8 @@ void value_t::print(std::ostream& out,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
out << "<POINTER>";
|
out << "<SCOPE>";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -1647,8 +1647,8 @@ void value_t::dump(std::ostream& out, const bool relaxed) const
|
||||||
out << '/' << as_mask() << '/';
|
out << '/' << as_mask() << '/';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
out << boost::unsafe_any_cast<const void *>(&as_any_pointer());
|
out << as_scope();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQUENCE: {
|
case SEQUENCE: {
|
||||||
|
|
|
||||||
64
src/value.h
64
src/value.h
|
|
@ -56,6 +56,8 @@ namespace ledger {
|
||||||
|
|
||||||
DECLARE_EXCEPTION(value_error, std::runtime_error);
|
DECLARE_EXCEPTION(value_error, std::runtime_error);
|
||||||
|
|
||||||
|
class scope_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class value_t
|
* @class value_t
|
||||||
*
|
*
|
||||||
|
|
@ -107,7 +109,7 @@ 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
|
||||||
POINTER // an opaque pointer of any type
|
SCOPE // a pointer to a scope
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -134,7 +136,7 @@ private:
|
||||||
string, // STRING
|
string, // STRING
|
||||||
mask_t, // MASK
|
mask_t, // MASK
|
||||||
sequence_t *, // SEQUENCE
|
sequence_t *, // SEQUENCE
|
||||||
boost::any // POINTER
|
scope_t * // SCOPE
|
||||||
> data;
|
> data;
|
||||||
|
|
||||||
type_t type;
|
type_t type;
|
||||||
|
|
@ -332,10 +334,9 @@ public:
|
||||||
set_sequence(val);
|
set_sequence(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
explicit value_t(scope_t * item) {
|
||||||
explicit value_t(T * item) {
|
TRACE_CTOR(value_t, "scope_t *");
|
||||||
TRACE_CTOR(value_t, "T *");
|
set_scope(item);
|
||||||
set_pointer(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -687,50 +688,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dealing with pointers is bit involved because we actually deal
|
* Dealing with scope pointers.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
bool is_pointer() const {
|
bool is_scope() const {
|
||||||
return is_type(POINTER);
|
return is_type(SCOPE);
|
||||||
}
|
}
|
||||||
boost::any& as_any_pointer_lval() {
|
scope_t * as_scope() const {
|
||||||
VERIFY(is_pointer());
|
VERIFY(is_scope());
|
||||||
_dup();
|
return boost::get<scope_t *>(storage->data);
|
||||||
return boost::get<boost::any>(storage->data);
|
|
||||||
}
|
}
|
||||||
template <typename T>
|
void set_scope(scope_t * val) {
|
||||||
T * as_pointer_lval() {
|
set_type(SCOPE);
|
||||||
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);
|
|
||||||
storage->data = val;
|
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
|
* Data conversion methods. These methods convert a value object to
|
||||||
|
|
@ -902,8 +872,8 @@ public:
|
||||||
return _("a regexp");
|
return _("a regexp");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
return _("a sequence");
|
return _("a sequence");
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
return _("a pointer");
|
return _("a scope");
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue