/*============================================================================= Copyright (c) 2005-2010 Joel de Guzman Copyright (c) 2010 Eric Niebler Copyright (c) 2010 Thomas Heller 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) ==============================================================================*/ #ifndef BOOST_PHOENIX_CORE_META_GRAMMAR_HPP #define BOOST_PHOENIX_CORE_META_GRAMMAR_HPP #include <boost/phoenix/core/limits.hpp> #include <boost/mpl/deref.hpp> #include <boost/phoenix/core/environment.hpp> #include <boost/proto/matches.hpp> #include <boost/proto/transform/call.hpp> #include <boost/proto/transform/default.hpp> namespace boost { namespace phoenix { ///////////////////////////////////////////////////////////////////////////// // The grammar defining valid phoenix expressions struct meta_grammar : proto::switch_<meta_grammar> { template <typename Tag, typename Dummy = void> struct case_ : proto::not_<proto::_> {}; }; struct evaluator { BOOST_PROTO_TRANSFORM(evaluator) template <typename Expr, typename State, typename Data> struct impl : proto::transform_impl<Expr, State, Data> { typedef meta_grammar::impl<Expr, State, Data> what; typedef typename what::result_type result_type; result_type operator()( typename impl::expr_param e , typename impl::state_param s , typename impl::data_param d ) const { return what()(e, s, d); } }; template <typename Expr, typename State> struct impl<Expr, State, proto::empty_env> : proto::transform_impl<Expr, State, proto::empty_env> { typedef meta_grammar::impl< Expr , typename result_of::env<State>::type , typename result_of::actions<State>::type > what; typedef typename what::result_type result_type; result_type operator()( typename impl::expr_param e , typename impl::state_param s , typename impl::data_param ) const { return what()(e, phoenix::env(s), actions(s)); } }; template <typename Expr, typename State> struct impl<Expr, State, unused> : proto::transform_impl<Expr, State, unused> { typedef meta_grammar::impl< Expr , typename result_of::env<State>::type , typename result_of::actions<State>::type > what; typedef typename what::result_type result_type; result_type operator()( typename impl::expr_param e , typename impl::state_param s , typename impl::data_param ) const { return what()(e, phoenix::env(s), actions(s)); } }; }; ///////////////////////////////////////////////////////////////////////////// // Set of default actions. Extend this whenever you add a new phoenix // construct struct default_actions { template <typename Rule, typename Dummy = void> struct when : proto::_default<meta_grammar> {}; }; template <typename Rule, typename Dummy = void> struct enable_rule : proto::when<Rule, proto::external_transform> {}; namespace result_of { template <typename Expr, typename Context> struct eval : boost::result_of< ::boost::phoenix::evaluator(Expr, Context)> {}; } ///////////////////////////////////////////////////////////////////////////// // A function we can call to evaluate our expression template <typename Expr, typename Context> inline typename meta_grammar::template impl< Expr const& , typename result_of::env<Context const&>::type , typename result_of::actions<Context const&>::type >::result_type eval(Expr const& expr, Context const & ctx) { static evaluator const e = {}; return e(expr, ctx); } template <typename Expr, typename Context> inline typename meta_grammar::template impl< Expr & , typename result_of::env<Context const&>::type , typename result_of::actions<Context const&>::type >::result_type eval(Expr & expr, Context const & ctx) { static evaluator const e = {}; return e(expr, ctx); } }} #endif