2
0
mirror of https://github.com/boostorg/phoenix.git synced 2026-02-09 23:32:16 +00:00
Files
phoenix/example/custom_evaluator.cpp
2010-08-18 23:02:48 +00:00

171 lines
5.1 KiB
C++

/*==============================================================================
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)
==============================================================================*/
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/proto/proto.hpp>
#include <iostream>
#include <typeinfo>
namespace proto = boost::proto;
namespace phoenix = boost::phoenix;
namespace impl
{
template <typename OutStream>
struct phoenix_to_cpp
{
phoenix_to_cpp( OutStream& ostr ) : ostr(ostr), level(1) {};
OutStream& ostr;
int level;
template <typename Expr, typename Tag = typename proto::tag_of<Expr>::type>
struct eval
: proto::null_eval<Expr, phoenix_to_cpp>
{};
template <typename Expr>
struct eval<Expr, proto::tag::minus>
{
typedef OutStream& result_type;
result_type operator()(Expr &expr, phoenix_to_cpp &ctx) const
{
proto::eval(proto::child_c<0>(expr), ctx);
ctx.ostr << " - ";
proto::eval(proto::child_c<1>(expr), ctx);
return ctx.ostr;
}
};
template <typename Expr>
struct eval<Expr, proto::tag::plus>
{
typedef OutStream& result_type;
result_type operator()(Expr &expr, phoenix_to_cpp &ctx) const
{
proto::eval(proto::child_c<0>(expr), ctx);
ctx.ostr << " + ";
proto::eval(proto::child_c<1>(expr), ctx);
return ctx.ostr;
}
};
template <typename Expr>
struct eval<Expr, proto::tag::comma>
{
typedef OutStream& result_type;
result_type operator()(Expr &expr, phoenix_to_cpp &ctx) const
{
/*ctx.ostr << std::setw(ctx.level*4) << " ";*/ proto::eval(proto::child_c<0>(expr), ctx);
ctx.ostr << ";\n";
/*ctx.ostr << std::setw(ctx.level*4) << " ";*/ proto::eval(proto::child_c<1>(expr), ctx);
ctx.ostr << ";";
return ctx.ostr;
}
};
template <typename Expr>
struct eval<Expr, proto::tag::function>
{
typedef OutStream& result_type;
template <typename E>
void output(OutStream& os, E const& expr) const
{
std::cout << typeid( expr ).name() << "\n\n";
std::cout << typeid( typename phoenix::make_argument<boost::mpl::int_<0> >::type ).name() << "\n\n";
}
void output(OutStream& os, typename phoenix::make_argument<boost::mpl::int_<0> >::type const& expr)
{
os << "arg" << 0;
}
void output(OutStream& os, typename phoenix::make_argument<boost::mpl::int_<1> >::type const& expr)
{
os << "arg" << 1;
}
void output(OutStream& os, typename phoenix::make_argument<boost::mpl::int_<2> >::type const& expr)
{
os << "arg" << 2;
}
void output(OutStream& os, typename phoenix::make_argument<boost::mpl::int_<3> >::type const& expr)
{
os << "arg" << 3;
}
/*phoenix::actor<
proto::basic_expr<
boost::proto::tag::function
, proto::list3<
proto::basic_expr<
proto::tag::terminal
, proto::term< phoenix::funcwrap<phoenix::argument> >
>
, Env
, proto::basic_expr<
proto::tag::terminal
, proto::term< N >
>
>
>
> const& expr) const */
result_type operator()(Expr &expr, phoenix_to_cpp &ctx) const
{
output( ctx.ostr, expr );
return ctx.ostr;
}
};
};
}
template <typename Expr>
void phoenix_to_cpp(Expr const& expr)
{
std::cout << "template <typename Result";
for( unsigned i = 0; i < phoenix::arity(expr); ++i )
{
std::cout << ", typename Arg" << i;
}
std::cout << ">\n";
std::cout << "Result f(";
for( unsigned i = 0; i < phoenix::arity(expr); ++i )
{
std::cout << "Arg" << i << " arg" << i;
if( i != phoenix::arity(expr)-1 ) std::cout << ", ";
}
std::cout << ")\n{\n";
impl::phoenix_to_cpp<std::ostream> ctx(std::cout);
proto::eval( expr, ctx );
std::cout << "\n}\n";
}
int main()
{
using phoenix::arg_names::arg1;
using phoenix::arg_names::arg2;
using phoenix::arg_names::arg3;
phoenix_to_cpp( (arg1 + arg2, arg1 - arg2, arg1 + arg2 - arg3 ) );
}