Chris@16: /*============================================================================= Chris@16: Copyright (c) 2001-2011 Joel de Guzman Chris@16: Copyright (c) 2001-2011 Hartmut Kaiser Chris@16: Copyright (c) 2011 Thomas Heller Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: ==============================================================================*/ Chris@16: #if !defined(BOOST_SPIRIT_CONTEXT_OCTOBER_31_2008_0654PM) Chris@16: #define BOOST_SPIRIT_CONTEXT_OCTOBER_31_2008_0654PM Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: Chris@16: #define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \ Chris@16: typedef phoenix::actor > \ Chris@16: BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \ Chris@16: phoenix::actor > const \ Chris@16: BOOST_PP_CAT(_r, n) = BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type)(); Chris@16: /***/ Chris@16: #define SPIRIT_USING_ATTRIBUTE(z, n, data) \ Chris@16: using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \ Chris@16: using spirit::BOOST_PP_CAT(_r, n); \ Chris@16: /***/ Chris@16: Chris@16: #else Chris@16: Chris@16: #define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \ Chris@16: typedef phoenix::actor > \ Chris@16: BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \ Chris@16: /***/ Chris@16: #define SPIRIT_USING_ATTRIBUTE(z, n, data) \ Chris@16: using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \ Chris@16: /***/ Chris@16: Chris@16: #endif Chris@16: Chris@16: namespace boost { namespace spirit Chris@16: { Chris@16: template Chris@16: struct attribute; Chris@16: Chris@16: template Chris@16: struct local_variable; Chris@16: }} Chris@16: Chris@16: BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( Chris@16: template Chris@16: , boost::spirit::attribute Chris@16: , mpl::false_ // is not nullary Chris@16: , v2_eval( Chris@16: proto::make< Chris@16: boost::spirit::attribute() Chris@16: > Chris@16: , proto::call< Chris@16: functional::env(proto::_state) Chris@16: > Chris@16: ) Chris@16: ) Chris@16: Chris@16: BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL( Chris@16: template Chris@16: , boost::spirit::local_variable Chris@16: , mpl::false_ // is not nullary Chris@16: , v2_eval( Chris@16: proto::make< Chris@16: boost::spirit::local_variable() Chris@16: > Chris@16: , proto::call< Chris@16: functional::env(proto::_state) Chris@16: > Chris@16: ) Chris@16: ) Chris@16: Chris@16: namespace boost { namespace spirit Chris@16: { Chris@16: template Chris@16: struct context Chris@16: { Chris@16: typedef Attributes attributes_type; Chris@16: typedef Locals locals_type; Chris@16: Chris@16: context(typename Attributes::car_type attribute) Chris@101: : attributes(attribute, fusion::nil_()), locals() {} Chris@16: Chris@16: template Chris@16: context( Chris@16: typename Attributes::car_type attribute Chris@16: , Args const& args Chris@16: , Context& caller_context Chris@16: ) : attributes( Chris@16: attribute Chris@16: , fusion::as_list( Chris@16: fusion::transform( Chris@16: args Chris@16: , detail::expand_arg(caller_context) Chris@16: ) Chris@16: ) Chris@16: ) Chris@16: , locals() {} Chris@16: Chris@16: context(Attributes const& attributes_) Chris@16: : attributes(attributes_), locals() {} Chris@16: Chris@16: Attributes attributes; // The attributes Chris@16: Locals locals; // Local variables Chris@16: }; Chris@16: Chris@16: template Chris@16: struct attributes_of Chris@16: { Chris@16: typedef typename Context::attributes_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct attributes_of Chris@16: { Chris@16: typedef typename Context::attributes_type const type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct attributes_of Chris@16: : attributes_of Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct locals_of Chris@16: { Chris@16: typedef typename Context::locals_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct locals_of Chris@16: { Chris@16: typedef typename Context::locals_type const type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct locals_of Chris@16: { Chris@16: typedef typename Context::locals_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct attribute Chris@16: { Chris@16: typedef mpl::true_ no_nullary; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename Chris@16: attributes_of::type Chris@16: >::type Chris@16: attributes_type; Chris@16: Chris@16: typedef typename Chris@16: fusion::result_of::size::type Chris@16: attributes_size; Chris@16: Chris@16: // report invalid argument not found (N is out of bounds) Chris@16: BOOST_SPIRIT_ASSERT_MSG( Chris@16: (N < attributes_size::value), Chris@16: index_is_out_of_bounds, ()); Chris@16: Chris@16: typedef typename Chris@16: fusion::result_of::at_c::type Chris@16: type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename result::type Chris@16: eval(Env const& env) const Chris@16: { Chris@16: return fusion::at_c((fusion::at_c<1>(env.args())).attributes); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct local_variable Chris@16: { Chris@16: typedef mpl::true_ no_nullary; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename Chris@16: locals_of::type Chris@16: >::type Chris@16: locals_type; Chris@16: Chris@16: typedef typename Chris@16: fusion::result_of::size::type Chris@16: locals_size; Chris@16: Chris@16: // report invalid argument not found (N is out of bounds) Chris@16: BOOST_SPIRIT_ASSERT_MSG( Chris@16: (N < locals_size::value), Chris@16: index_is_out_of_bounds, ()); Chris@16: Chris@16: typedef typename Chris@16: fusion::result_of::at_c::type Chris@16: type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename result::type Chris@16: eval(Env const& env) const Chris@16: { Chris@16: return get_arg((fusion::at_c<1>(env.args())).locals); Chris@16: } Chris@16: }; Chris@16: Chris@16: typedef phoenix::actor > _val_type; Chris@16: typedef phoenix::actor > _r0_type; Chris@16: typedef phoenix::actor > _r1_type; Chris@16: typedef phoenix::actor > _r2_type; Chris@16: Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: // _val refers to the 'return' value of a rule (same as _r0) Chris@16: // _r1, _r2, ... refer to the rule arguments Chris@16: _val_type const _val = _val_type(); Chris@16: _r0_type const _r0 = _r0_type(); Chris@16: _r1_type const _r1 = _r1_type(); Chris@16: _r2_type const _r2 = _r2_type(); Chris@16: #endif Chris@16: Chris@16: // Bring in the rest of the attributes (_r4 .. _rN+1), using PP Chris@16: BOOST_PP_REPEAT_FROM_TO( Chris@16: 3, SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_DECLARE_ATTRIBUTE, _) Chris@16: Chris@16: typedef phoenix::actor > _a_type; Chris@16: typedef phoenix::actor > _b_type; Chris@16: typedef phoenix::actor > _c_type; Chris@16: typedef phoenix::actor > _d_type; Chris@16: typedef phoenix::actor > _e_type; Chris@16: typedef phoenix::actor > _f_type; Chris@16: typedef phoenix::actor > _g_type; Chris@16: typedef phoenix::actor > _h_type; Chris@16: typedef phoenix::actor > _i_type; Chris@16: typedef phoenix::actor > _j_type; Chris@16: Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: // _a, _b, ... refer to the local variables of a rule Chris@16: _a_type const _a = _a_type(); Chris@16: _b_type const _b = _b_type(); Chris@16: _c_type const _c = _c_type(); Chris@16: _d_type const _d = _d_type(); Chris@16: _e_type const _e = _e_type(); Chris@16: _f_type const _f = _f_type(); Chris@16: _g_type const _g = _g_type(); Chris@16: _h_type const _h = _h_type(); Chris@16: _i_type const _i = _i_type(); Chris@16: _j_type const _j = _j_type(); Chris@16: #endif Chris@16: Chris@16: // You can bring these in with the using directive Chris@16: // without worrying about bringing in too much. Chris@16: namespace labels Chris@16: { Chris@16: BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _) Chris@16: BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _) Chris@16: Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: using spirit::_val; Chris@16: using spirit::_a; Chris@16: using spirit::_b; Chris@16: using spirit::_c; Chris@16: using spirit::_d; Chris@16: using spirit::_e; Chris@16: using spirit::_f; Chris@16: using spirit::_g; Chris@16: using spirit::_h; Chris@16: using spirit::_i; Chris@16: using spirit::_j; Chris@16: #endif Chris@16: } Chris@16: }} Chris@16: Chris@16: #endif