let.hpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*==============================================================================
  2. Copyright (c) 2001-2010 Joel de Guzman
  3. Copyright (c) 2004 Daniel Wallin
  4. Copyright (c) 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. #ifndef BOOST_PHOENIX_SCOPE_LET_HPP
  9. #define BOOST_PHOENIX_SCOPE_LET_HPP
  10. #include <boost/phoenix/core/limits.hpp>
  11. #include <boost/fusion/include/transform.hpp>
  12. #include <boost/fusion/include/as_vector.hpp>
  13. #include <boost/phoenix/core/call.hpp>
  14. #include <boost/phoenix/core/expression.hpp>
  15. #include <boost/phoenix/core/meta_grammar.hpp>
  16. #include <boost/phoenix/scope/scoped_environment.hpp>
  17. #include <boost/phoenix/scope/local_variable.hpp>
  18. #include <boost/phoenix/support/iterate.hpp>
  19. #include <boost/phoenix/support/vector.hpp>
  20. BOOST_PHOENIX_DEFINE_EXPRESSION(
  21. (boost)(phoenix)(let_)
  22. , (proto::terminal<proto::_>) // Locals
  23. (proto::terminal<proto::_>) // Map
  24. (meta_grammar)
  25. )
  26. namespace boost { namespace phoenix
  27. {
  28. struct let_eval
  29. {
  30. template <typename Sig>
  31. struct result;
  32. template <typename This, typename Vars, typename Map, typename Expr, typename Context>
  33. struct result<This(Vars, Map, Expr, Context)>
  34. {
  35. typedef
  36. typename proto::detail::uncvref<
  37. typename result_of::env<Context>::type
  38. >::type
  39. env_type;
  40. typedef
  41. typename proto::detail::uncvref<
  42. typename result_of::actions<Context>::type
  43. >::type
  44. actions_type;
  45. typedef
  46. typename proto::detail::uncvref<
  47. typename proto::result_of::value<Vars>::type
  48. >::type
  49. vars_type;
  50. typedef
  51. typename proto::detail::uncvref<
  52. typename proto::result_of::value<Map>::type
  53. >::type
  54. map_type;
  55. typedef typename
  56. detail::result_of::initialize_locals<
  57. vars_type
  58. , Context
  59. >::type
  60. locals_type;
  61. typedef typename
  62. result_of::eval<
  63. Expr
  64. , typename result_of::context<
  65. scoped_environment<
  66. env_type
  67. , env_type
  68. , locals_type
  69. , map_type
  70. >
  71. , actions_type
  72. >::type
  73. >::type
  74. type;
  75. };
  76. template <typename Vars, typename Map, typename Expr, typename Context>
  77. typename result<let_eval(Vars const&, Map const&, Expr const &, Context const &)>::type const
  78. operator()(Vars const & vars, Map, Expr const & expr, Context const & ctx) const
  79. {
  80. typedef
  81. typename proto::detail::uncvref<
  82. typename result_of::env<Context>::type
  83. >::type
  84. env_type;
  85. typedef
  86. typename proto::detail::uncvref<
  87. typename proto::result_of::value<Vars>::type
  88. >::type
  89. vars_type;
  90. typedef
  91. typename proto::detail::uncvref<
  92. typename proto::result_of::value<Map>::type
  93. >::type
  94. map_type;
  95. typedef typename
  96. detail::result_of::initialize_locals<
  97. vars_type
  98. , Context
  99. >::type
  100. locals_type;
  101. locals_type locals = initialize_locals(proto::value(vars), ctx);
  102. scoped_environment<
  103. env_type
  104. , env_type
  105. , locals_type
  106. , map_type
  107. >
  108. env(phoenix::env(ctx), phoenix::env(ctx), locals);
  109. return eval(expr, phoenix::context(env, phoenix::actions(ctx)));
  110. }
  111. };
  112. template <typename Dummy>
  113. struct default_actions::when<rule::let_, Dummy>
  114. : call<let_eval, Dummy>
  115. {};
  116. template <typename Locals, typename Map>
  117. struct let_actor_gen
  118. {
  119. let_actor_gen(Locals const & locals)
  120. : locals(locals)
  121. {}
  122. let_actor_gen(let_actor_gen const & o)
  123. : locals(o.locals)
  124. {}
  125. template <typename Expr>
  126. typename expression::let_<
  127. Locals
  128. , Map
  129. , Expr
  130. >::type const
  131. operator[](Expr const & expr) const
  132. {
  133. return expression::let_<Locals, Map, Expr>::make(locals, Map(), expr);
  134. }
  135. Locals locals;
  136. };
  137. #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME let_actor_gen
  138. #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION let
  139. #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST
  140. #include <boost/phoenix/scope/detail/local_gen.hpp>
  141. #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME
  142. #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION
  143. #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST
  144. template <typename Dummy>
  145. struct is_nullary::when<rule::let_, Dummy>
  146. : proto::make<
  147. mpl::and_<
  148. proto::fold<
  149. proto::call<proto::_value(proto::_child_c<0>)>
  150. , proto::make<mpl::true_()>
  151. , proto::make<
  152. mpl::and_<
  153. proto::_state
  154. , proto::call<
  155. evaluator(
  156. proto::_
  157. , _context
  158. , proto::make<proto::empty_env()>
  159. )
  160. >
  161. >()
  162. >
  163. >
  164. , evaluator(
  165. proto::_child_c<2>
  166. , proto::call<
  167. functional::context(
  168. proto::make<
  169. mpl::true_()
  170. >
  171. , proto::make<
  172. detail::scope_is_nullary_actions()
  173. >
  174. )
  175. >
  176. , proto::make<
  177. proto::empty_env()
  178. >
  179. )
  180. >()
  181. >
  182. {};
  183. }}
  184. #endif