blob: f79f305f1ce4e438cd13c937f2d5828b2cddd809 [file] [log] [blame]
/*=============================================================================
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, int>
: proto::transform_impl<Expr, State, int>
{
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, 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, 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