let.hpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*==============================================================================
  2. Copyright (c) 2001-2010 Joel de Guzman
  3. Copyright (c) 2004 Daniel Wallin
  4. Copyright (c) 2010 Thomas Heller
  5. Copyright (c) 2015 John Fletcher
  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. #ifndef BOOST_PHOENIX_SCOPE_LET_HPP
  10. #define BOOST_PHOENIX_SCOPE_LET_HPP
  11. //#include <boost/assert.hpp>
  12. //#include <sstream>
  13. #include <boost/phoenix/core/limits.hpp>
  14. #include <boost/fusion/include/transform.hpp>
  15. #include <boost/fusion/include/as_vector.hpp>
  16. #include <boost/phoenix/core/call.hpp>
  17. #include <boost/phoenix/core/expression.hpp>
  18. #include <boost/phoenix/core/meta_grammar.hpp>
  19. #include <boost/phoenix/scope/scoped_environment.hpp>
  20. #include <boost/phoenix/scope/local_variable.hpp>
  21. #include <boost/phoenix/support/iterate.hpp>
  22. #include <boost/phoenix/support/vector.hpp>
  23. BOOST_PHOENIX_DEFINE_EXPRESSION(
  24. (boost)(phoenix)(let_)
  25. , (proto::terminal<proto::_>) // Locals
  26. (proto::terminal<proto::_>) // Map
  27. (meta_grammar)
  28. )
  29. namespace boost { namespace phoenix
  30. {
  31. struct let_eval
  32. {
  33. template <typename Sig>
  34. struct result;
  35. template <typename This, typename Vars, typename Map, typename Expr, typename Context>
  36. struct result<This(Vars, Map, Expr, Context)>
  37. {
  38. typedef
  39. typename proto::detail::uncvref<
  40. typename result_of::env<Context>::type
  41. >::type
  42. env_type;
  43. typedef
  44. typename proto::detail::uncvref<
  45. typename result_of::actions<Context>::type
  46. >::type
  47. actions_type;
  48. typedef
  49. typename proto::detail::uncvref<
  50. typename proto::result_of::value<Vars>::type
  51. >::type
  52. vars_type;
  53. typedef
  54. typename proto::detail::uncvref<
  55. typename proto::result_of::value<Map>::type
  56. >::type
  57. map_type;
  58. typedef
  59. typename proto::detail::uncvref<Expr>::type
  60. expr_type;
  61. typedef typename
  62. detail::result_of::initialize_locals<
  63. vars_type
  64. , Context
  65. >::type
  66. locals_type;
  67. typedef typename
  68. result_of::eval<
  69. expr_type
  70. , typename result_of::context<
  71. scoped_environment<
  72. env_type
  73. , env_type
  74. , locals_type
  75. , map_type
  76. >
  77. , actions_type
  78. >::type
  79. >::type
  80. type;
  81. };
  82. template <typename Vars, typename Map, typename Expr, typename Context>
  83. typename result<let_eval(Vars const&, Map const&, Expr const &, Context const &)>::type const
  84. operator()(Vars const & vars, Map, Expr const & expr, Context const & ctx) const
  85. {
  86. Vars vars_(vars);
  87. typedef
  88. typename proto::detail::uncvref<
  89. typename result_of::env<Context>::type
  90. >::type
  91. env_type;
  92. typedef
  93. typename proto::detail::uncvref<
  94. typename proto::result_of::value<Vars>::type
  95. >::type
  96. vars_type;
  97. typedef
  98. typename proto::detail::uncvref<
  99. typename proto::result_of::value<Map>::type
  100. >::type
  101. map_type;
  102. typedef typename
  103. detail::result_of::initialize_locals<
  104. vars_type
  105. , Context
  106. >::type
  107. locals_type;
  108. locals_type locals = initialize_locals(proto::value(vars_), ctx);
  109. //typedef typename result<let_eval(Vars const&, Map const&, Expr const &, Context const &)>::type result_type;
  110. scoped_environment<
  111. env_type
  112. , env_type
  113. , locals_type
  114. , map_type
  115. >
  116. env(phoenix::env(ctx), phoenix::env(ctx), locals);
  117. // Fix for bugs (trial)
  118. // The idea is to do something which will not be optimised away.
  119. //int vsize = boost::fusion::size(vars);
  120. //std::stringstream strm;
  121. //strm << vsize << std::endl;
  122. //int size = strm.str().length();
  123. //BOOST_ASSERT(size >= 0);
  124. return eval(expr, phoenix::context(env, phoenix::actions(ctx)));
  125. // typedef is_value<result_type> is_val;
  126. //if(is_val::value) This seems always to be true
  127. //{
  128. // std::cout << "let result has value type" << std::endl;
  129. // }
  130. //if (is_val(r) ) std::cout << "let returns val" << std::endl;
  131. //std::cout << "result is " << r << std::endl;
  132. //return r;
  133. }
  134. };
  135. template <typename Dummy>
  136. struct default_actions::when<rule::let_, Dummy>
  137. : call<let_eval, Dummy>
  138. {};
  139. template <typename Locals, typename Map>
  140. struct let_actor_gen
  141. {
  142. let_actor_gen(Locals const & locals_)
  143. : locals(locals_)
  144. {}
  145. let_actor_gen(let_actor_gen const & o)
  146. : locals(o.locals)
  147. {}
  148. template <typename Expr>
  149. typename expression::let_<
  150. Locals
  151. , Map
  152. , Expr
  153. >::type const
  154. operator[](Expr const & expr) const
  155. {
  156. typedef typename expression::let_<
  157. Locals
  158. , Map
  159. , Expr
  160. >::type let_type;
  161. //typedef is_value<let_type> is_val;
  162. let_type let_exp = expression::let_<Locals, Map, Expr>::make(locals, Map(), expr);
  163. //if(is_val::value) //This seems always to be true
  164. //{
  165. // std::cout << "let has value type" << std::endl;
  166. //}
  167. return let_exp;
  168. }
  169. Locals locals;
  170. };
  171. #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME let_actor_gen
  172. #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION let
  173. #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST
  174. #if defined(BOOST_PHOENIX_NO_VARIADIC_SCOPE)
  175. #include <boost/phoenix/scope/detail/cpp03/local_gen.hpp>
  176. #else
  177. #include <boost/phoenix/scope/detail/local_gen.hpp>
  178. #endif
  179. #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME
  180. #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION
  181. #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST
  182. template <typename Dummy>
  183. struct is_nullary::when<rule::let_, Dummy>
  184. : proto::make<
  185. mpl::and_<
  186. proto::fold<
  187. proto::call<proto::_value(proto::_child_c<0>)>
  188. , proto::make<mpl::true_()>
  189. , proto::make<
  190. mpl::and_<
  191. proto::_state
  192. , proto::call<
  193. evaluator(
  194. proto::_
  195. , _context
  196. , proto::make<proto::empty_env()>
  197. )
  198. >
  199. >()
  200. >
  201. >
  202. , evaluator(
  203. proto::_child_c<2>
  204. , proto::call<
  205. functional::context(
  206. proto::make<
  207. mpl::true_()
  208. >
  209. , proto::make<
  210. detail::scope_is_nullary_actions()
  211. >
  212. )
  213. >
  214. , proto::make<
  215. proto::empty_env()
  216. >
  217. )
  218. >()
  219. >
  220. {};
  221. }}
  222. #endif