123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- [/==============================================================================
- Copyright (C) 2001-2010 Joel de Guzman
- Copyright (C) 2001-2005 Dan Marsden
- Copyright (C) 2001-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)
- ===============================================================================/]
- [section Adding an expression]
- This is not a toy example. This is actually part of the library. Remember the
- [link phoenix.modules.statement.while__statement `while`] lazy statement? Putting together
- everything we've learned so far, we eill present it here in its entirety
- (verbatim):
- BOOST_PHOENIX_DEFINE_EXPRESSION(
- (boost)(phoenix)(while_)
- , (meta_grammar) // Cond
- (meta_grammar) // Do
- )
- namespace boost { namespace phoenix
- {
- struct while_eval
- {
- typedef void result_type;
- template <typename Cond, typename Do, typename Context>
- result_type
- operator()(Cond const& cond, Do const& do_, Context & ctx) const
- {
- while(eval(cond, ctx))
- {
- eval(do_, ctx);
- }
- }
- };
-
- template <typename Dummy>
- struct default_actions::when<rule::while_, Dummy>
- : call<while_eval, Dummy>
- {};
- template <typename Cond>
- struct while_gen
- {
- while_gen(Cond const& cond) : cond(cond) {}
- template <typename Do>
- typename expression::while_<Cond, Do>::type const
- operator[](Do const& do_) const
- {
- return expression::while_<Cond, Do>::make(cond, do_);
- }
- Cond const& cond;
- };
- template <typename Cond>
- while_gen<Cond> const
- while_(Cond const& cond)
- {
- return while_gen<Cond>(cond);
- }
- }}
- `while_eval` is an example of how to evaluate an expression. It gets called in
- the `rule::while` action. `while_gen` and `while_` are the expression template
- front ends. Let's break this apart to undestand what's happening. Let's start at
- the bottom. It's easier that way.
- When you write:
- while_(cond)
- we generate an instance of `while_gen<Cond>`, where `Cond` is the type of `cond`.
- `cond` can be an arbitrarily complex actor expression. The `while_gen` template
- class has an `operator[]` accepting another expression. If we write:
- while_(cond)
- [
- do_
- ]
- it will generate a proper composite with the type:
- expression::while_<Cond, Do>::type
- where `Cond` is the type of `cond` and `Do` is the type of `do_`. Notice how we are using Phoenix's
- [link phoenix.inside.expression Expression] mechanism here
-
- template <typename Do>
- typename expression::while_<Cond, Do>::type const
- operator[](Do const& do_) const
- {
- return expression::while_<Cond, Do>::make(cond, do_);
- }
- Finally, the `while_eval` does its thing:
- while(eval(cond, ctx))
- {
- eval(do_, ctx);
- }
- `cond` and `do_`, at this point, are instances of [link phoenix.inside.actor Actor]. `cond` and `do_` are the [link phoenix.inside.actor Actors]
- passed as parameters by `call`, ctx is the [link phoenix.inside.actor Context]
- [endsect]
|