adding.qbk 3.4 KB

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