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