
On Sun, Feb 28, 2010 at 1:28 AM, Eric Niebler <eric@boostpro.com> wrote:
On 2/28/2010 7:17 PM, Manjunath Kudlur wrote:
I am trying to define operator()(...) for my expressions. I want to be able to form expression of the form Program_(a,b) and call Program_(a, b)(10,20). Here, 'a' and 'b' are terminals and I have a mechanism shown in the code below that somehow gets the type suitable for the parameter position. Suppose 'a' is terminal<Var<int> >, I want the first parameter position in Program_(a,b) (pos1, pos2) to be of the type 'int'.
<snip>
OK.
template<int N> struct call_param_type : proto::or_< proto::when< proto::function< proto::terminal<program_>, proto::vararg<proto::terminal<Var<proto::_> > > >, var_type(proto::_child_c<N+1>)>
{};
OK, the call_param_type grammar only matches expressions of the type Program_(a, b).
template<typename Expr> struct program_expr { BOOST_PROTO_BASIC_EXTENDS(Expr, program_expr<Expr>, program_domain); BOOST_PROTO_EXTENDS_SUBSCRIPT();
typedef void result_type;
#if 0 result_type operator()(typename boost::result_of<call_param_type<0>(const Expr&)>::type x) { std::cout<< "program with one arg\n"; }
<snip>
This function definition eagerly evaluates the call_param_type grammar's transform against Expr regardless of whether Expr matches call_param_type's grammar or not. Trouble. Look at how you define the Program_ function:
template<typename A0> typename proto::result_of::make_expr<proto::tag::function , program_domain , program_ , A0 const &>::type const Program_(A0 const &a0)
This creates an expression node with tag type "tag::function" and two children: a program_ terminal and A0. When make_expr turns program_ into a Proto terminal, it uses program_domain to wrap the terminal in a program_expr. That's bad news because a program_ terminal doesn't match the call_param_type grammar. You're violating the transform's precondition.
Yeah, got it. I realise now that the passing a domain to make_expr wraps all the components of the expression also with the corresponding expression class. What I am unable to figure out it how to wrap only the final expression I want with program_expr. In this case I want to wrap expr<tag::function, vararg<terminal<Var> > > with program_expr. Is there an example I can look at that does something similar? Or is this the wrong way to look at the problem? Basically, I want to add the function call operator to my expressions, but only to expressions of certain forms. My thinking is, if I only wrap expressions of that certain form with my expression class, I should be OK, no? Manjunath
Suggestion: when you are having problems with evaluating a transform, try adding an MPL assertion that the expression you're passing to it actually matches the grammar.
HTH,
-- Eric Niebler BoostPro Computing http://www.boostpro.com _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users