statements.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. /*=============================================================================
  2. Phoenix V1.2.1
  3. Copyright (c) 2001-2002 Joel de Guzman
  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. #ifndef PHOENIX_STATEMENTS_HPP
  8. #define PHOENIX_STATEMENTS_HPP
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #include <boost/spirit/home/classic/phoenix/composite.hpp>
  11. ///////////////////////////////////////////////////////////////////////////////
  12. namespace phoenix {
  13. ///////////////////////////////////////////////////////////////////////////////
  14. //
  15. // sequential_composite
  16. //
  17. // Two or more actors separated by the comma generates a
  18. // sequential_composite which is a composite actor. Example:
  19. //
  20. // actor,
  21. // actor,
  22. // actor
  23. //
  24. // The actors are evaluated sequentially. The result type of this
  25. // is void. Note that the last actor should not have a trailing
  26. // comma.
  27. //
  28. ///////////////////////////////////////////////////////////////////////////////
  29. template <typename A0, typename A1>
  30. struct sequential_composite {
  31. typedef sequential_composite<A0, A1> self_t;
  32. template <typename TupleT>
  33. struct result { typedef void type; };
  34. sequential_composite(A0 const& _0, A1 const& _1)
  35. : a0(_0), a1(_1) {}
  36. template <typename TupleT>
  37. void
  38. eval(TupleT const& args) const
  39. {
  40. a0.eval(args);
  41. a1.eval(args);
  42. }
  43. A0 a0; A1 a1; // actors
  44. };
  45. //////////////////////////////////
  46. template <typename BaseT0, typename BaseT1>
  47. inline actor<sequential_composite<actor<BaseT0>, actor<BaseT1> > >
  48. operator,(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
  49. {
  50. return sequential_composite<actor<BaseT0>, actor<BaseT1> >(_0, _1);
  51. }
  52. ///////////////////////////////////////////////////////////////////////////////
  53. //
  54. // if_then_else_composite
  55. //
  56. // This composite has two (2) forms:
  57. //
  58. // if_(condition)
  59. // [
  60. // statement
  61. // ]
  62. //
  63. // and
  64. //
  65. // if_(condition)
  66. // [
  67. // true_statement
  68. // ]
  69. // .else_
  70. // [
  71. // false_statement
  72. // ]
  73. //
  74. // where condition is an actor that evaluates to bool. If condition
  75. // is true, the true_statement (again an actor) is executed
  76. // otherwise, the false_statement (another actor) is executed. The
  77. // result type of this is void. Note the trailing underscore after
  78. // if_ and the leading dot and the trailing underscore before
  79. // and after .else_.
  80. //
  81. ///////////////////////////////////////////////////////////////////////////////
  82. template <typename CondT, typename ThenT, typename ElseT>
  83. struct if_then_else_composite {
  84. typedef if_then_else_composite<CondT, ThenT, ElseT> self_t;
  85. template <typename TupleT>
  86. struct result {
  87. typedef void type;
  88. };
  89. if_then_else_composite(
  90. CondT const& cond_,
  91. ThenT const& then_,
  92. ElseT const& else__)
  93. : cond(cond_), then(then_), else_(else__) {}
  94. template <typename TupleT>
  95. void eval(TupleT const& args) const
  96. {
  97. if (cond.eval(args))
  98. then.eval(args);
  99. else
  100. else_.eval(args);
  101. }
  102. CondT cond; ThenT then; ElseT else_; // actors
  103. };
  104. //////////////////////////////////
  105. template <typename CondT, typename ThenT>
  106. struct else_gen {
  107. else_gen(CondT const& cond_, ThenT const& then_)
  108. : cond(cond_), then(then_) {}
  109. template <typename ElseT>
  110. actor<if_then_else_composite<CondT, ThenT,
  111. typename as_actor<ElseT>::type> >
  112. operator[](ElseT const& else_)
  113. {
  114. typedef if_then_else_composite<CondT, ThenT,
  115. typename as_actor<ElseT>::type>
  116. result;
  117. return result(cond, then, as_actor<ElseT>::convert(else_));
  118. }
  119. CondT cond; ThenT then;
  120. };
  121. //////////////////////////////////
  122. template <typename CondT, typename ThenT>
  123. struct if_then_composite {
  124. typedef if_then_composite<CondT, ThenT> self_t;
  125. template <typename TupleT>
  126. struct result { typedef void type; };
  127. if_then_composite(CondT const& cond_, ThenT const& then_)
  128. : cond(cond_), then(then_), else_(cond, then) {}
  129. template <typename TupleT>
  130. void eval(TupleT const& args) const
  131. {
  132. if (cond.eval(args))
  133. then.eval(args);
  134. }
  135. CondT cond; ThenT then; // actors
  136. else_gen<CondT, ThenT> else_;
  137. };
  138. //////////////////////////////////
  139. template <typename CondT>
  140. struct if_gen {
  141. if_gen(CondT const& cond_)
  142. : cond(cond_) {}
  143. template <typename ThenT>
  144. actor<if_then_composite<
  145. typename as_actor<CondT>::type,
  146. typename as_actor<ThenT>::type> >
  147. operator[](ThenT const& then) const
  148. {
  149. typedef if_then_composite<
  150. typename as_actor<CondT>::type,
  151. typename as_actor<ThenT>::type>
  152. result;
  153. return result(
  154. as_actor<CondT>::convert(cond),
  155. as_actor<ThenT>::convert(then));
  156. }
  157. CondT cond;
  158. };
  159. //////////////////////////////////
  160. template <typename CondT>
  161. inline if_gen<CondT>
  162. if_(CondT const& cond)
  163. {
  164. return if_gen<CondT>(cond);
  165. }
  166. ///////////////////////////////////////////////////////////////////////////////
  167. //
  168. // while_composite
  169. //
  170. // This composite has the form:
  171. //
  172. // while_(condition)
  173. // [
  174. // statement
  175. // ]
  176. //
  177. // While the condition (an actor) evaluates to true, statement
  178. // (another actor) is executed. The result type of this is void.
  179. // Note the trailing underscore after while_.
  180. //
  181. ///////////////////////////////////////////////////////////////////////////////
  182. template <typename CondT, typename DoT>
  183. struct while_composite {
  184. typedef while_composite<CondT, DoT> self_t;
  185. template <typename TupleT>
  186. struct result { typedef void type; };
  187. while_composite(CondT const& cond_, DoT const& do__)
  188. : cond(cond_), do_(do__) {}
  189. template <typename TupleT>
  190. void eval(TupleT const& args) const
  191. {
  192. while (cond.eval(args))
  193. do_.eval(args);
  194. }
  195. CondT cond;
  196. DoT do_;
  197. };
  198. //////////////////////////////////
  199. template <typename CondT>
  200. struct while_gen {
  201. while_gen(CondT const& cond_)
  202. : cond(cond_) {}
  203. template <typename DoT>
  204. actor<while_composite<
  205. typename as_actor<CondT>::type,
  206. typename as_actor<DoT>::type> >
  207. operator[](DoT const& do_) const
  208. {
  209. typedef while_composite<
  210. typename as_actor<CondT>::type,
  211. typename as_actor<DoT>::type>
  212. result;
  213. return result(
  214. as_actor<CondT>::convert(cond),
  215. as_actor<DoT>::convert(do_));
  216. }
  217. CondT cond;
  218. };
  219. //////////////////////////////////
  220. template <typename CondT>
  221. inline while_gen<CondT>
  222. while_(CondT const& cond)
  223. {
  224. return while_gen<CondT>(cond);
  225. }
  226. ///////////////////////////////////////////////////////////////////////////////
  227. //
  228. // do_composite
  229. //
  230. // This composite has the form:
  231. //
  232. // do_
  233. // [
  234. // statement
  235. // ]
  236. // .while_(condition)
  237. //
  238. // While the condition (an actor) evaluates to true, statement
  239. // (another actor) is executed. The statement is executed at least
  240. // once. The result type of this is void. Note the trailing
  241. // underscore after do_ and the leading dot and the trailing
  242. // underscore before and after .while_.
  243. //
  244. ///////////////////////////////////////////////////////////////////////////////
  245. template <typename DoT, typename CondT>
  246. struct do_composite {
  247. typedef do_composite<DoT, CondT> self_t;
  248. template <typename TupleT>
  249. struct result { typedef void type; };
  250. do_composite(DoT const& do__, CondT const& cond_)
  251. : do_(do__), cond(cond_) {}
  252. template <typename TupleT>
  253. void eval(TupleT const& args) const
  254. {
  255. do
  256. do_.eval(args);
  257. while (cond.eval(args));
  258. }
  259. DoT do_;
  260. CondT cond;
  261. };
  262. ////////////////////////////////////
  263. template <typename DoT>
  264. struct do_gen2 {
  265. do_gen2(DoT const& do__)
  266. : do_(do__) {}
  267. template <typename CondT>
  268. actor<do_composite<
  269. typename as_actor<DoT>::type,
  270. typename as_actor<CondT>::type> >
  271. while_(CondT const& cond) const
  272. {
  273. typedef do_composite<
  274. typename as_actor<DoT>::type,
  275. typename as_actor<CondT>::type>
  276. result;
  277. return result(
  278. as_actor<DoT>::convert(do_),
  279. as_actor<CondT>::convert(cond));
  280. }
  281. DoT do_;
  282. };
  283. ////////////////////////////////////
  284. struct do_gen {
  285. template <typename DoT>
  286. do_gen2<DoT>
  287. operator[](DoT const& do_) const
  288. {
  289. return do_gen2<DoT>(do_);
  290. }
  291. };
  292. do_gen const do_ = do_gen();
  293. ///////////////////////////////////////////////////////////////////////////////
  294. //
  295. // for_composite
  296. //
  297. // This statement has the form:
  298. //
  299. // for_(init, condition, step)
  300. // [
  301. // statement
  302. // ]
  303. //
  304. // Where init, condition, step and statement are all actors. init
  305. // is executed once before entering the for-loop. The for-loop
  306. // exits once condition evaluates to false. At each loop iteration,
  307. // step and statement is called. The result of this statement is
  308. // void. Note the trailing underscore after for_.
  309. //
  310. ///////////////////////////////////////////////////////////////////////////////
  311. template <typename InitT, typename CondT, typename StepT, typename DoT>
  312. struct for_composite {
  313. typedef composite<InitT, CondT, StepT, DoT> self_t;
  314. template <typename TupleT>
  315. struct result { typedef void type; };
  316. for_composite(
  317. InitT const& init_,
  318. CondT const& cond_,
  319. StepT const& step_,
  320. DoT const& do__)
  321. : init(init_), cond(cond_), step(step_), do_(do__) {}
  322. template <typename TupleT>
  323. void
  324. eval(TupleT const& args) const
  325. {
  326. for (init.eval(args); cond.eval(args); step.eval(args))
  327. do_.eval(args);
  328. }
  329. InitT init; CondT cond; StepT step; DoT do_; // actors
  330. };
  331. //////////////////////////////////
  332. template <typename InitT, typename CondT, typename StepT>
  333. struct for_gen {
  334. for_gen(
  335. InitT const& init_,
  336. CondT const& cond_,
  337. StepT const& step_)
  338. : init(init_), cond(cond_), step(step_) {}
  339. template <typename DoT>
  340. actor<for_composite<
  341. typename as_actor<InitT>::type,
  342. typename as_actor<CondT>::type,
  343. typename as_actor<StepT>::type,
  344. typename as_actor<DoT>::type> >
  345. operator[](DoT const& do_) const
  346. {
  347. typedef for_composite<
  348. typename as_actor<InitT>::type,
  349. typename as_actor<CondT>::type,
  350. typename as_actor<StepT>::type,
  351. typename as_actor<DoT>::type>
  352. result;
  353. return result(
  354. as_actor<InitT>::convert(init),
  355. as_actor<CondT>::convert(cond),
  356. as_actor<StepT>::convert(step),
  357. as_actor<DoT>::convert(do_));
  358. }
  359. InitT init; CondT cond; StepT step;
  360. };
  361. //////////////////////////////////
  362. template <typename InitT, typename CondT, typename StepT>
  363. inline for_gen<InitT, CondT, StepT>
  364. for_(InitT const& init, CondT const& cond, StepT const& step)
  365. {
  366. return for_gen<InitT, CondT, StepT>(init, cond, step);
  367. }
  368. } // namespace phoenix
  369. #endif