/*============================================================================= Copyright (c) 2001-2011 Joel de Guzman Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #if !defined(BOOST_SPIRIT_CONTEXT_OCTOBER_31_2008_0654PM) #define BOOST_SPIRIT_CONTEXT_OCTOBER_31_2008_0654PM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #include #include #include #include #if !defined(SPIRIT_ATTRIBUTES_LIMIT) # define SPIRIT_ATTRIBUTES_LIMIT PHOENIX_LIMIT #endif #define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \ phoenix::actor > const \ BOOST_PP_CAT(_r, n) = attribute(); #define SPIRIT_USING_ATTRIBUTE(z, n, data) using spirit::BOOST_PP_CAT(_r, n); namespace boost { namespace spirit { template struct context { typedef Attributes attributes_type; typedef Locals locals_type; context(typename Attributes::car_type attribute) : attributes(attribute, fusion::nil()), locals() {} template context( typename Attributes::car_type attribute , Args const& args , Context& caller_context ) : attributes( attribute , fusion::as_list( fusion::transform( args , detail::expand_arg(caller_context) ) ) ) , locals() {} context(Attributes const& attributes) : attributes(attributes), locals() {} Attributes attributes; // The attributes Locals locals; // Local variables }; template struct attributes_of { typedef typename Context::attributes_type type; }; template struct attributes_of { typedef typename Context::attributes_type const type; }; template struct locals_of { typedef typename Context::locals_type type; }; template struct locals_of { typedef typename Context::locals_type const type; }; template struct attribute { typedef mpl::true_ no_nullary; template struct result { typedef typename attributes_of::type >::type attributes_type; typedef typename fusion::result_of::size::type attributes_size; // report invalid argument not found (N is out of bounds) BOOST_SPIRIT_ASSERT_MSG( (N < attributes_size::value), index_is_out_of_bounds, ()); typedef typename fusion::result_of::at_c::type type; }; template typename result::type eval(Env const& env) const { return fusion::at_c((fusion::at_c<1>(env.args())).attributes); } }; template struct local_variable { typedef mpl::true_ no_nullary; template struct result { typedef typename locals_of::type >::type locals_type; typedef typename fusion::result_of::size::type locals_size; // report invalid argument not found (N is out of bounds) BOOST_SPIRIT_ASSERT_MSG( (N < locals_size::value), index_is_out_of_bounds, ()); typedef typename fusion::result_of::at_c::type type; }; template typename result::type eval(Env const& env) const { return get_arg((fusion::at_c<1>(env.args())).locals); } }; // _val refers to the 'return' value of a rule (same as _r0) // _r1, _r2, ... refer to the rule arguments phoenix::actor > const _val = attribute<0>(); phoenix::actor > const _r0 = attribute<0>(); phoenix::actor > const _r1 = attribute<1>(); phoenix::actor > const _r2 = attribute<2>(); // Bring in the rest of the attributes (_r4 .. _rN+1), using PP BOOST_PP_REPEAT_FROM_TO( 3, SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_DECLARE_ATTRIBUTE, _) // _a, _b, ... refer to the local variables of a rule phoenix::actor > const _a = local_variable<0>(); phoenix::actor > const _b = local_variable<1>(); phoenix::actor > const _c = local_variable<2>(); phoenix::actor > const _d = local_variable<3>(); phoenix::actor > const _e = local_variable<4>(); phoenix::actor > const _f = local_variable<5>(); phoenix::actor > const _g = local_variable<6>(); phoenix::actor > const _h = local_variable<7>(); phoenix::actor > const _i = local_variable<8>(); phoenix::actor > const _j = local_variable<9>(); // You can bring these in with the using directive // without worrying about bringing in too much. namespace labels { BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _) BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _) using spirit::_val; using spirit::_a; using spirit::_b; using spirit::_c; using spirit::_d; using spirit::_e; using spirit::_f; using spirit::_g; using spirit::_h; using spirit::_i; using spirit::_j; } }} #endif