Boost logo

Proto :

Subject: Re: [proto] Visitor Design Pattern
From: Eric Niebler (eric_at_[hidden])
Date: 2010-10-25 16:30:48

On 10/25/2010 9:26 AM, Eric Niebler wrote:
> On 10/25/2010 4:44 AM, Thomas Heller wrote:
>> Thank you very much! So, we are good to changing the internals of
>> phoenix3 to use this extension mechanism?
> Yes. But today I'm going to made some changes, based on my experience
> playing with this code last night. In particular, it should be possible
> to have *only* the named rules be customization points; for all other
> rules, actions are attached to rules the old way via proto::when. I
> think that if we pass the Actions bundle as the Data parameter to the
> transforms, these things become possible.

Oh /man/ this makes things so much simpler. By passing the actions at
the data parameter, not only do we get the above benefits, but we don't
need to parameterize the actions on any action sub-classes. The
implementation is totally trivial and very simple:

Here is a grammar with actions, some of which are specified externally:

    struct my_grammar
      : proto::or_<
            proto::when< int_terminal, proto::external >
          , proto::when< char_terminal, proto::external >
          , proto::when<
                proto::plus< my_grammar, my_grammar >
              , proto::fold< _, int(), my_grammar >

Duh, right? Now you define the actions for the two customization points:

    struct my_actions
        template <typename Grammar>
        struct when;

    struct my_actions::when<int_terminal>
      : proto::call<print(proto::_value)>

    struct my_actions::when<char_terminal>
      : proto::call<print(char(boost::mpl::char_<'x'>()))>

You evaluate expressions by passing them to my_grammar per usual,
passing an instance of my_actions as the (little used) data parameter:

    my_actions act;
    my_grammar()(a + i, 0, act);

Voila! The implementation is trivial: one specialization of proto::when
on the new (incomplete) proto::external type. God, why didn't I think of
this sooner?

The naming issue goes away completely. There is no fancy new proto
transform to be named. Also, proto::named_rule goes away, too.

I'm attaching Thomas' (now laughably trivial) traversal_proto.cpp
example, along with my mini Phoenix, both ported to this new scheme. The
mini-Phoenix takes the extra step of bundling the actions with the
parameters into the phoenix environment (doing the unpacking/repacking
under the covers as necessary).

One potential further simplification would be to give users a nicer way
to map rules to actions. I'll think about it.

Eric Niebler
BoostPro Computing

Proto list run by eric at