From bc9ff7095fbfa1812e4f47dbf8531dec76cd0d00 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 20 Feb 2012 17:20:16 -0600 Subject: Introduced a new SCOPE expression terminal --- src/op.h | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) (limited to 'src/op.h') diff --git a/src/op.h b/src/op.h index 6f7d7904..c4d353dc 100644 --- a/src/op.h +++ b/src/op.h @@ -58,10 +58,12 @@ private: mutable short refc; ptr_op_t left_; - variant // used by terminal SCOPE > data; public: @@ -73,6 +75,7 @@ public: CONSTANTS, FUNCTION, + SCOPE, TERMINALS, @@ -173,7 +176,7 @@ public: return kind == FUNCTION; } expr_t::func_t& as_function_lval() { - assert(kind == FUNCTION); + assert(is_function()); return boost::get(data); } const expr_t::func_t& as_function() const { @@ -183,21 +186,41 @@ public: data = val; } + bool is_scope() const { + return kind == SCOPE; + } + bool is_scope_unset() const { + return data.which() == 0; + } + shared_ptr as_scope_lval() { + assert(is_scope()); + return boost::get >(data); + } + const shared_ptr as_scope() const { + return const_cast(this)->as_scope_lval(); + } + void set_scope(shared_ptr val) { + data = val; + } + + // These three functions must use 'kind == IDENT' rather than + // 'is_ident()', because they are called before the `data' member gets + // set, which is_ident() tests. ptr_op_t& left() { - assert(kind > TERMINALS || kind == IDENT); + assert(kind > TERMINALS || kind == IDENT || is_scope()); return left_; } const ptr_op_t& left() const { - assert(kind > TERMINALS || kind == IDENT); + assert(kind > TERMINALS || kind == IDENT || is_scope()); return left_; } void set_left(const ptr_op_t& expr) { - assert(kind > TERMINALS || kind == IDENT); + assert(kind > TERMINALS || kind == IDENT || is_scope()); left_ = expr; } ptr_op_t& as_op_lval() { - assert(kind > TERMINALS || kind == IDENT); + assert(kind > TERMINALS || is_ident()); return boost::get(data); } const ptr_op_t& as_op() const { @@ -219,7 +242,7 @@ public: bool has_right() const { if (kind < TERMINALS) return false; - return as_op(); + return data.which() != 0 && as_op(); } private: @@ -284,6 +307,7 @@ public: static ptr_op_t wrap_value(const value_t& val); static ptr_op_t wrap_functor(expr_t::func_t fobj); + static ptr_op_t wrap_scope(shared_ptr sobj); #if defined(HAVE_BOOST_SERIALIZATION) private: @@ -295,13 +319,13 @@ private: void serialize(Archive& ar, const unsigned int /* version */) { ar & refc; ar & kind; - if (Archive::is_loading::value || ! left_ || left_->kind != FUNCTION) { + if (Archive::is_loading::value || ! left_ || ! left_->is_function()) { ar & left_; } else { ptr_op_t temp_op; ar & temp_op; } - if (Archive::is_loading::value || kind == VALUE || kind == IDENT || + if (Archive::is_loading::value || is_value() || is_ident() || (kind > UNARY_OPERATORS && (! has_right() || ! right()->is_function()))) { ar & data; @@ -335,6 +359,13 @@ expr_t::op_t::wrap_functor(expr_t::func_t fobj) { return temp; } +inline expr_t::ptr_op_t +expr_t::op_t::wrap_scope(shared_ptr sobj) { + ptr_op_t temp(new op_t(op_t::SCOPE)); + temp->set_scope(sobj); + return temp; +} + #define MAKE_FUNCTOR(x) expr_t::op_t::wrap_functor(bind(&x, this, _1)) #define WRAP_FUNCTOR(x) expr_t::op_t::wrap_functor(x) -- cgit v1.2.3