1 | // Copyright (c) 2001-2011 Hartmut Kaiser |
2 | // Copyright (c) 2011 Thomas Heller |
3 | // |
4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | |
7 | #if !defined(BOOST_SPIRIT_LEX_ARGUMENT_PHEONIX_MARCH_25_2011_1841PM) |
8 | #define BOOST_SPIRIT_LEX_ARGUMENT_PHEONIX_MARCH_25_2011_1841PM |
9 | |
10 | #if defined(_MSC_VER) |
11 | #pragma once |
12 | #endif |
13 | |
14 | #include <boost/phoenix/core/actor.hpp> |
15 | #include <boost/phoenix/core/as_actor.hpp> |
16 | #include <boost/phoenix/core/expression.hpp> |
17 | #include <boost/phoenix/core/v2_eval.hpp> |
18 | #include <boost/phoenix/core/value.hpp> // includes as_actor specialization |
19 | #include <boost/proto/traits.hpp> |
20 | #include <boost/proto/proto_fwd.hpp> // for transform placeholders |
21 | |
22 | namespace boost { namespace spirit { namespace lex |
23 | { |
24 | /////////////////////////////////////////////////////////////////////////// |
25 | // The value_context is used as a noop Phoenix actor to create the |
26 | // placeholder '_val' (see below). It is a noop actor because it is used |
27 | // as a placeholder only, while it is being converted either to a |
28 | // value_getter (if used as a rvalue) or to a value_setter (if used as a |
29 | // lvalue). The conversion is achieved by specializing and overloading a |
30 | // couple of the Phoenix templates from the Phoenix expression composition |
31 | // engine (see the end of this file). |
32 | struct value_context |
33 | { |
34 | typedef mpl::true_ no_nullary; |
35 | |
36 | typedef unused_type result_type; |
37 | |
38 | template <typename Env> |
39 | struct result |
40 | { |
41 | typedef unused_type type; |
42 | }; |
43 | |
44 | template <typename Env> |
45 | unused_type |
46 | eval(Env const&) const |
47 | { |
48 | return unused; |
49 | } |
50 | }; |
51 | |
52 | // forward declarations |
53 | struct value_getter; |
54 | template <typename> struct value_setter; |
55 | |
56 | /////////////////////////////////////////////////////////////////////////// |
57 | // The state_context is used as a noop Phoenix actor to create the |
58 | // placeholder '_state' (see below). It is a noop actor because it is used |
59 | // as a placeholder only, while it is being converted either to a |
60 | // state_getter (if used as a rvalue) or to a state_setter (if used as a |
61 | // lvalue). The conversion is achieved by specializing and overloading a |
62 | // couple of the Phoenix templates from the Phoenix expression composition |
63 | // engine (see the end of this file). |
64 | struct state_context |
65 | { |
66 | typedef mpl::true_ no_nullary; |
67 | |
68 | typedef unused_type result_type; |
69 | |
70 | template <typename Env> |
71 | struct result |
72 | { |
73 | typedef unused_type type; |
74 | }; |
75 | |
76 | template <typename Env> |
77 | unused_type |
78 | eval(Env const&) const |
79 | { |
80 | return unused; |
81 | } |
82 | }; |
83 | |
84 | // forward declarations |
85 | struct state_getter; |
86 | template <typename> struct state_setter; |
87 | struct eoi_getter; |
88 | }}} |
89 | |
90 | /////////////////////////////////////////////////////////////////////////////// |
91 | |
92 | BOOST_PHOENIX_DEFINE_EXPRESSION( |
93 | (boost)(spirit)(lex)(value_setter) |
94 | , (boost::phoenix::meta_grammar) |
95 | ) |
96 | |
97 | BOOST_PHOENIX_DEFINE_EXPRESSION( |
98 | (boost)(spirit)(lex)(state_setter) |
99 | , (boost::phoenix::meta_grammar) |
100 | ) |
101 | |
102 | namespace boost { namespace phoenix |
103 | { |
104 | namespace result_of |
105 | { |
106 | template <> |
107 | struct is_nullary<custom_terminal<boost::spirit::lex::value_context> > |
108 | : mpl::false_ |
109 | {}; |
110 | } |
111 | |
112 | template <typename Dummy> |
113 | struct is_custom_terminal<boost::spirit::lex::value_context, Dummy>: mpl::true_ {}; |
114 | |
115 | template <typename Dummy> |
116 | struct custom_terminal<boost::spirit::lex::value_context, Dummy> |
117 | : proto::call< |
118 | v2_eval( |
119 | proto::make<boost::spirit::lex::value_getter()> |
120 | , proto::call<functional::env(proto::_state)> |
121 | ) |
122 | > |
123 | {}; |
124 | |
125 | template <typename Dummy> |
126 | struct is_nullary::when<spirit::lex::rule::value_setter, Dummy> |
127 | : proto::make<mpl::false_()> |
128 | {}; |
129 | |
130 | template <typename Dummy> |
131 | struct default_actions::when<spirit::lex::rule::value_setter, Dummy> |
132 | : proto::call< |
133 | v2_eval( |
134 | proto::make< |
135 | spirit::lex::value_setter<proto::_child0>( |
136 | proto::_child0 |
137 | ) |
138 | > |
139 | , _env |
140 | ) |
141 | > |
142 | {}; |
143 | |
144 | template <> |
145 | struct actor<spirit::lex::value_context> |
146 | : boost::phoenix::actor<proto::terminal<spirit::lex::value_context>::type> |
147 | { |
148 | typedef boost::phoenix::actor< |
149 | proto::terminal<spirit::lex::value_context>::type |
150 | > base_type; |
151 | |
152 | actor(base_type const & base = base_type()) |
153 | : base_type(base) |
154 | {} |
155 | |
156 | template <typename Expr> |
157 | typename spirit::lex::expression::value_setter< |
158 | typename phoenix::as_actor<Expr>::type>::type const |
159 | operator=(Expr const & expr) const |
160 | { |
161 | return |
162 | spirit::lex::expression::value_setter< |
163 | typename phoenix::as_actor<Expr>::type |
164 | >::make(phoenix::as_actor<Expr>::convert(expr)); |
165 | } |
166 | }; |
167 | |
168 | namespace result_of |
169 | { |
170 | template <> |
171 | struct is_nullary<custom_terminal<boost::spirit::lex::state_context> > |
172 | : mpl::false_ |
173 | {}; |
174 | } |
175 | |
176 | template <typename Dummy> |
177 | struct is_custom_terminal<boost::spirit::lex::state_context, Dummy>: mpl::true_ {}; |
178 | |
179 | template <typename Dummy> |
180 | struct custom_terminal<boost::spirit::lex::state_context, Dummy> |
181 | : proto::call< |
182 | v2_eval( |
183 | proto::make<boost::spirit::lex::state_getter()> |
184 | , proto::call<functional::env(proto::_state)> |
185 | ) |
186 | > |
187 | {}; |
188 | |
189 | template <typename Dummy> |
190 | struct is_nullary::when<spirit::lex::rule::state_setter, Dummy> |
191 | : proto::make<mpl::false_()> |
192 | {}; |
193 | |
194 | template <typename Dummy> |
195 | struct default_actions::when<spirit::lex::rule::state_setter, Dummy> |
196 | : proto::call< |
197 | v2_eval( |
198 | proto::make< |
199 | spirit::lex::state_setter<proto::_child0>( |
200 | proto::_child0 |
201 | ) |
202 | > |
203 | , _env |
204 | ) |
205 | > |
206 | {}; |
207 | |
208 | template <> |
209 | struct actor<spirit::lex::state_context> |
210 | : boost::phoenix::actor<proto::terminal<spirit::lex::state_context>::type> |
211 | { |
212 | typedef boost::phoenix::actor< |
213 | proto::terminal<spirit::lex::state_context>::type |
214 | > base_type; |
215 | |
216 | actor(base_type const & base = base_type()) |
217 | : base_type(base) |
218 | {} |
219 | |
220 | template <typename Expr> |
221 | typename spirit::lex::expression::state_setter< |
222 | typename phoenix::as_actor<Expr>::type>::type const |
223 | operator=(Expr const & expr) const |
224 | { |
225 | return |
226 | spirit::lex::expression::state_setter< |
227 | typename phoenix::as_actor<Expr>::type |
228 | >::make(phoenix::as_actor<Expr>::convert(expr)); |
229 | } |
230 | }; |
231 | |
232 | namespace result_of |
233 | { |
234 | template <> |
235 | struct is_nullary<custom_terminal<boost::spirit::lex::eoi_getter> > |
236 | : mpl::false_ |
237 | {}; |
238 | } |
239 | |
240 | template <typename Dummy> |
241 | struct is_custom_terminal<boost::spirit::lex::eoi_getter, Dummy>: mpl::true_ {}; |
242 | |
243 | template <typename Dummy> |
244 | struct custom_terminal<boost::spirit::lex::eoi_getter, Dummy> |
245 | : proto::call< |
246 | v2_eval( |
247 | proto::make<boost::spirit::lex::eoi_getter()> |
248 | , proto::call<functional::env(proto::_state)> |
249 | ) |
250 | > |
251 | {}; |
252 | }} |
253 | |
254 | #endif |
255 | |