1[/============================================================================== 2 Copyright (C) 2001-2010 Joel de Guzman 3 Copyright (C) 2001-2005 Dan Marsden 4 Copyright (C) 2001-2010 Thomas Heller 5 6 Distributed under the Boost Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8===============================================================================/] 9 10[section Adding an expression] 11 12This is not a toy example. This is actually part of the library. Remember the 13[link phoenix.modules.statement.while__statement `while`] lazy statement? Putting together 14everything we've learned so far, we eill present it here in its entirety 15(verbatim): 16 17 BOOST_PHOENIX_DEFINE_EXPRESSION( 18 (boost)(phoenix)(while_) 19 , (meta_grammar) // Cond 20 (meta_grammar) // Do 21 ) 22 23 namespace boost { namespace phoenix 24 { 25 struct while_eval 26 { 27 typedef void result_type; 28 29 template <typename Cond, typename Do, typename Context> 30 result_type 31 operator()(Cond const& cond, Do const& do_, Context & ctx) const 32 { 33 while(eval(cond, ctx)) 34 { 35 eval(do_, ctx); 36 } 37 } 38 }; 39 40 template <typename Dummy> 41 struct default_actions::when<rule::while_, Dummy> 42 : call<while_eval, Dummy> 43 {}; 44 45 template <typename Cond> 46 struct while_gen 47 { 48 while_gen(Cond const& cond) : cond(cond) {} 49 50 template <typename Do> 51 typename expression::while_<Cond, Do>::type const 52 operator[](Do const& do_) const 53 { 54 return expression::while_<Cond, Do>::make(cond, do_); 55 } 56 57 Cond const& cond; 58 }; 59 60 template <typename Cond> 61 while_gen<Cond> const 62 while_(Cond const& cond) 63 { 64 return while_gen<Cond>(cond); 65 } 66 }} 67 68`while_eval` is an example of how to evaluate an expression. It gets called in 69the `rule::while` action. `while_gen` and `while_` are the expression template 70front ends. Let's break this apart to undestand what's happening. Let's start at 71the bottom. It's easier that way. 72 73When you write: 74 75 while_(cond) 76 77we generate an instance of `while_gen<Cond>`, where `Cond` is the type of `cond`. 78`cond` can be an arbitrarily complex actor expression. The `while_gen` template 79class has an `operator[]` accepting another expression. If we write: 80 81 while_(cond) 82 [ 83 do_ 84 ] 85 86it will generate a proper composite with the type: 87 88 expression::while_<Cond, Do>::type 89 90where `Cond` is the type of `cond` and `Do` is the type of `do_`. Notice how we are using Phoenix's 91[link phoenix.inside.expression Expression] mechanism here 92 93 template <typename Do> 94 typename expression::while_<Cond, Do>::type const 95 operator[](Do const& do_) const 96 { 97 return expression::while_<Cond, Do>::make(cond, do_); 98 } 99 100Finally, the `while_eval` does its thing: 101 102 while(eval(cond, ctx)) 103 { 104 eval(do_, ctx); 105 } 106 107`cond` and `do_`, at this point, are instances of [link phoenix.inside.actor Actor]. `cond` and `do_` are the [link phoenix.inside.actor Actors] 108passed as parameters by `call`, ctx is the [link phoenix.inside.actor Context] 109 110[endsect] 111 112