1 /*============================================================================= 2 Copyright (c) 2005-2010 Joel de Guzman 3 Copyright (c) 2010 Eric Niebler 4 Copyright (c) 2010 Thomas Heller 5 6 Distributed under the Boost Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 ==============================================================================*/ 9 #ifndef BOOST_PHOENIX_CORE_META_GRAMMAR_HPP 10 #define BOOST_PHOENIX_CORE_META_GRAMMAR_HPP 11 12 #include <boost/phoenix/core/limits.hpp> 13 #include <boost/mpl/deref.hpp> 14 #include <boost/phoenix/core/environment.hpp> 15 #include <boost/proto/matches.hpp> 16 #include <boost/proto/transform/call.hpp> 17 #include <boost/proto/transform/default.hpp> 18 19 namespace boost { namespace phoenix 20 { 21 ///////////////////////////////////////////////////////////////////////////// 22 // The grammar defining valid phoenix expressions 23 struct meta_grammar 24 : proto::switch_<meta_grammar> 25 { 26 template <typename Tag, typename Dummy = void> 27 struct case_ 28 : proto::not_<proto::_> 29 {}; 30 }; 31 32 struct evaluator 33 { 34 BOOST_PROTO_TRANSFORM(evaluator) 35 36 template <typename Expr, typename State, typename Data> 37 struct impl 38 : proto::transform_impl<Expr, State, Data> 39 { 40 typedef meta_grammar::impl<Expr, State, Data> what; 41 42 typedef typename what::result_type result_type; 43 operator ()boost::phoenix::evaluator::impl44 result_type operator()( 45 typename impl::expr_param e 46 , typename impl::state_param s 47 , typename impl::data_param d 48 ) const 49 { 50 return what()(e, s, d); 51 } 52 }; 53 54 template <typename Expr, typename State> 55 struct impl<Expr, State, proto::empty_env> 56 : proto::transform_impl<Expr, State, proto::empty_env> 57 { 58 typedef 59 meta_grammar::impl< 60 Expr 61 , typename result_of::env<State>::type 62 , typename result_of::actions<State>::type 63 > 64 what; 65 66 typedef typename what::result_type result_type; 67 operator ()boost::phoenix::evaluator::impl68 result_type operator()( 69 typename impl::expr_param e 70 , typename impl::state_param s 71 , typename impl::data_param 72 ) const 73 { 74 return what()(e, phoenix::env(s), actions(s)); 75 } 76 }; 77 78 template <typename Expr, typename State> 79 struct impl<Expr, State, unused> 80 : proto::transform_impl<Expr, State, unused> 81 { 82 typedef 83 meta_grammar::impl< 84 Expr 85 , typename result_of::env<State>::type 86 , typename result_of::actions<State>::type 87 > 88 what; 89 90 typedef typename what::result_type result_type; 91 operator ()boost::phoenix::evaluator::impl92 result_type operator()( 93 typename impl::expr_param e 94 , typename impl::state_param s 95 , typename impl::data_param 96 ) const 97 { 98 return what()(e, phoenix::env(s), actions(s)); 99 } 100 }; 101 }; 102 103 ///////////////////////////////////////////////////////////////////////////// 104 // Set of default actions. Extend this whenever you add a new phoenix 105 // construct 106 struct default_actions 107 { 108 template <typename Rule, typename Dummy = void> 109 struct when 110 : proto::_default<meta_grammar> 111 {}; 112 }; 113 114 template <typename Rule, typename Dummy = void> 115 struct enable_rule 116 : proto::when<Rule, proto::external_transform> 117 {}; 118 119 namespace result_of 120 { 121 template <typename Expr, typename Context> 122 struct eval 123 : boost::result_of< ::boost::phoenix::evaluator(Expr, Context)> 124 {}; 125 } 126 127 ///////////////////////////////////////////////////////////////////////////// 128 // A function we can call to evaluate our expression 129 template <typename Expr, typename Context> 130 inline 131 typename meta_grammar::template impl< 132 Expr const& 133 , typename result_of::env<Context const&>::type 134 , typename result_of::actions<Context const&>::type 135 >::result_type eval(Expr const & expr,Context const & ctx)136 eval(Expr const& expr, Context const & ctx) 137 { 138 static evaluator const e = {}; 139 return e(expr, ctx); 140 } 141 142 template <typename Expr, typename Context> 143 inline 144 typename meta_grammar::template impl< 145 Expr & 146 , typename result_of::env<Context const&>::type 147 , typename result_of::actions<Context const&>::type 148 >::result_type eval(Expr & expr,Context const & ctx)149 eval(Expr & expr, Context const & ctx) 150 { 151 static evaluator const e = {}; 152 return e(expr, ctx); 153 } 154 }} 155 156 #endif 157