PageRenderTime 43ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/libs/spirit/example/scheme/scheme/interpreter.hpp

https://bitbucket.org/bosp/external-boost
C++ Header | 565 lines | 436 code | 76 blank | 53 comment | 19 complexity | f4d5c9cbc6b6794cc73578fc21fac5cb MD5 | raw file
Possible License(s): MIT
  1. /*=============================================================================
  2. Copyright (c) 2001-2010 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. =============================================================================*/
  6. #if !defined(BOOST_SPIRIT_SCHEME_INTERPRETER)
  7. #define BOOST_SPIRIT_SCHEME_INTERPRETER
  8. #include <list>
  9. #include <boost/function.hpp>
  10. #include <boost/foreach.hpp>
  11. #include <boost/array.hpp>
  12. #include <boost/scoped_array.hpp>
  13. #include <boost/preprocessor/repetition/enum_params.hpp>
  14. #include <boost/spirit/include/support_utree.hpp>
  15. #define SCHEME_COMPOSITE_LIMIT 10
  16. #if defined(BOOST_MSVC)
  17. # pragma warning(push)
  18. # pragma warning(disable: 4018)
  19. #endif
  20. namespace scheme
  21. {
  22. ///////////////////////////////////////////////////////////////////////////////
  23. // The runtime interpreter
  24. ///////////////////////////////////////////////////////////////////////////////
  25. using boost::spirit::utree;
  26. using boost::spirit::utree_type;
  27. using boost::spirit::scope;
  28. using boost::spirit::shallow;
  29. using boost::spirit::stored_function;
  30. using boost::spirit::function_base;
  31. using boost::spirit::binary_string;
  32. using boost::spirit::utf8_symbol;
  33. using boost::spirit::utf8_string;
  34. using boost::spirit::binary_range;
  35. using boost::spirit::utf8_symbol_range;
  36. using boost::spirit::utf8_string_range;
  37. using boost::spirit::nil;
  38. ///////////////////////////////////////////////////////////////////////////
  39. // typedefs
  40. ///////////////////////////////////////////////////////////////////////////
  41. struct function;
  42. typedef std::list<function> actor_list;
  43. ///////////////////////////////////////////////////////////////////////////
  44. // actor
  45. ///////////////////////////////////////////////////////////////////////////
  46. template <typename Derived>
  47. struct actor
  48. {
  49. typedef utree result_type;
  50. typedef actor<Derived> base_type;
  51. utree operator()(scope const& env) const
  52. {
  53. return derived().eval(env);
  54. }
  55. utree operator()() const
  56. {
  57. return derived().eval(scope());
  58. }
  59. template <typename A0>
  60. utree operator()(A0 const& _0) const
  61. {
  62. boost::array<utree, 1> elements;
  63. elements[0] = _0;
  64. return derived().eval(get_range(elements));
  65. }
  66. template <typename A0, typename A1>
  67. utree operator()(A0 const& _0, A1 const& _1) const
  68. {
  69. boost::array<utree, 2> elements;
  70. elements[0] = _0;
  71. elements[1] = _1;
  72. return derived().eval(get_range(elements));
  73. }
  74. // More operators
  75. #include <scheme/detail/function_call.hpp>
  76. template <std::size_t n>
  77. static scope
  78. get_range(boost::array<utree, n>& array)
  79. {
  80. return scope(array.begin(), array.end());
  81. }
  82. Derived const& derived() const
  83. {
  84. return *static_cast<Derived const*>(this);
  85. }
  86. };
  87. ///////////////////////////////////////////////////////////////////////////
  88. // function
  89. ///////////////////////////////////////////////////////////////////////////
  90. struct function : actor<function>
  91. {
  92. utree f;
  93. function()
  94. : f() {}
  95. function(utree const& f)
  96. : f(f) {}
  97. template <typename F>
  98. function(F const& f)
  99. : f(stored_function<F>(f))
  100. {
  101. }
  102. bool empty() const
  103. {
  104. return f.which() != utree_type::function_type;
  105. }
  106. utree eval(scope const& env) const
  107. {
  108. return f.eval(env);
  109. }
  110. };
  111. ///////////////////////////////////////////////////////////////////////////
  112. // values
  113. ///////////////////////////////////////////////////////////////////////////
  114. struct value_function : actor<value_function>
  115. {
  116. utree val;
  117. value_function(utree const& val) : val(val) {}
  118. utree eval(scope const& /*env*/) const
  119. {
  120. return utree(boost::ref(val));
  121. }
  122. };
  123. struct value
  124. {
  125. typedef function result_type;
  126. function operator()(utree const& val) const
  127. {
  128. return function(value_function(val));
  129. }
  130. };
  131. value const val = {};
  132. inline function protect(function const& f)
  133. {
  134. return val(f.f);
  135. }
  136. ///////////////////////////////////////////////////////////////////////////
  137. // arguments
  138. ///////////////////////////////////////////////////////////////////////////
  139. template <bool scoped = true>
  140. struct argument_function : actor<argument_function<scoped> >
  141. {
  142. std::size_t n;
  143. std::size_t level;
  144. argument_function(std::size_t n, std::size_t level = 0)
  145. : n(n),
  146. level(level)
  147. {}
  148. utree eval(scope const& env) const
  149. {
  150. scope const* eptr = &env;
  151. while (level != eptr->level())
  152. eptr = eptr->outer();
  153. utree const& arg = (*eptr)[n];
  154. if (arg.which() != utree_type::function_type)
  155. return utree(boost::ref(arg));
  156. else
  157. return arg.eval(*eptr);
  158. }
  159. };
  160. template <> // scoped = false
  161. struct argument_function<false> : actor<argument_function<false> >
  162. {
  163. std::size_t n;
  164. argument_function(std::size_t n, std::size_t level = 0)
  165. : n(n)
  166. {}
  167. utree eval(scope const& env) const
  168. {
  169. scope const* eptr = &env;
  170. utree const& arg = (*eptr)[n];
  171. if (arg.which() != utree_type::function_type)
  172. return utree(boost::ref(arg));
  173. else
  174. return arg.eval(*eptr);
  175. }
  176. };
  177. template <bool scoped = true>
  178. struct argument
  179. {
  180. typedef function result_type;
  181. function operator()(std::size_t n, std::size_t level = 0) const
  182. {
  183. return function(argument_function<scoped>(n, level));
  184. }
  185. };
  186. // scoped arg
  187. argument<true> const arg = {};
  188. // unscoped arg
  189. argument<false> const unscoped_arg = {};
  190. // unscoped args
  191. function const _1 = unscoped_arg(0);
  192. function const _2 = unscoped_arg(1);
  193. function const _3 = unscoped_arg(2);
  194. function const _4 = unscoped_arg(3);
  195. function const _5 = unscoped_arg(4);
  196. function const _6 = unscoped_arg(5);
  197. function const _7 = unscoped_arg(6);
  198. function const _8 = unscoped_arg(7);
  199. function const _9 = unscoped_arg(8);
  200. function const _10 = unscoped_arg(10);
  201. ///////////////////////////////////////////////////////////////////////////
  202. // variable arguments.
  203. // Collects the arguments from n to last in a utree list.
  204. ///////////////////////////////////////////////////////////////////////////
  205. template <bool scoped = true>
  206. struct vararg_function : actor<vararg_function<scoped> >
  207. {
  208. std::size_t n;
  209. std::size_t level;
  210. vararg_function(std::size_t n, std::size_t level = 0)
  211. : n(n),
  212. level(level)
  213. {}
  214. utree eval(scope const& env) const
  215. {
  216. scope const* eptr = &env;
  217. while (level != eptr->level())
  218. eptr = eptr->outer();
  219. utree result;
  220. for (std::size_t i = n; i < eptr->size(); ++i)
  221. {
  222. utree const& arg = (*eptr)[i];
  223. if (arg.which() != utree_type::function_type)
  224. result.push_back(utree(boost::ref(arg)));
  225. else
  226. result.push_back(arg.eval(*eptr));
  227. }
  228. return result;
  229. }
  230. };
  231. template <> // scoped = false
  232. struct vararg_function<false> : actor<vararg_function<false> >
  233. {
  234. std::size_t n;
  235. vararg_function(std::size_t n, std::size_t level = 0)
  236. : n(n)
  237. {}
  238. utree eval(scope const& env) const
  239. {
  240. scope const* eptr = &env;
  241. utree result;
  242. for (std::size_t i = n; i < eptr->size(); ++i)
  243. {
  244. utree const& arg = (*eptr)[i];
  245. if (arg.which() != utree_type::function_type)
  246. result.push_back(utree(boost::ref(arg)));
  247. else
  248. result.push_back(arg.eval(*eptr));
  249. }
  250. return result;
  251. }
  252. };
  253. template <bool scoped = true>
  254. struct vararg
  255. {
  256. typedef function result_type;
  257. function operator()(std::size_t n, std::size_t level = 0) const
  258. {
  259. return function(vararg_function<scoped>(n, level));
  260. }
  261. };
  262. // scoped varg
  263. vararg<true> const varg = {};
  264. // unscoped varg
  265. vararg<false> const unscoped_varg = {};
  266. // unscoped vargs
  267. function const _1_ = unscoped_varg(0);
  268. function const _2_ = unscoped_varg(1);
  269. function const _3_ = unscoped_varg(2);
  270. function const _4_ = unscoped_varg(3);
  271. function const _5_ = unscoped_varg(4);
  272. function const _6_ = unscoped_varg(5);
  273. function const _7_ = unscoped_varg(6);
  274. function const _8_ = unscoped_varg(7);
  275. function const _9_ = unscoped_varg(8);
  276. function const _10_ = unscoped_varg(10);
  277. ///////////////////////////////////////////////////////////////////////////
  278. // composite
  279. ///////////////////////////////////////////////////////////////////////////
  280. template <typename Derived>
  281. struct composite
  282. {
  283. typedef function result_type;
  284. typedef composite<Derived> base_type;
  285. function operator()(actor_list const& elements) const
  286. {
  287. return derived().compose(elements);
  288. }
  289. template <typename A0>
  290. function operator()(A0 const& _0) const
  291. {
  292. actor_list elements;
  293. elements.push_back(as_function(_0));
  294. return derived().compose(elements);
  295. }
  296. template <typename A0, typename A1>
  297. function operator()(A0 const& _0, A1 const& _1) const
  298. {
  299. actor_list elements;
  300. elements.push_back(as_function(_0));
  301. elements.push_back(as_function(_1));
  302. return derived().compose(elements);
  303. }
  304. // More operators
  305. #include <scheme/detail/composite_call.hpp>
  306. Derived const& derived() const
  307. {
  308. return *static_cast<Derived const*>(this);
  309. }
  310. template <typename T>
  311. static function as_function(T const& val)
  312. {
  313. return scheme::val(utree(val));
  314. }
  315. static function const& as_function(function const& f)
  316. {
  317. return f;
  318. }
  319. };
  320. ///////////////////////////////////////////////////////////////////////////
  321. // unary_function
  322. ///////////////////////////////////////////////////////////////////////////
  323. template <typename Derived>
  324. struct unary_function : actor<unary_function<Derived> >
  325. {
  326. function a;
  327. typedef unary_function<Derived> base_type;
  328. unary_function(function const& a)
  329. : a(a)
  330. {
  331. BOOST_ASSERT(!a.empty());
  332. }
  333. utree eval(scope const& env) const
  334. {
  335. return derived().eval(a(env));
  336. }
  337. Derived const& derived() const
  338. {
  339. return *static_cast<Derived const*>(this);
  340. }
  341. };
  342. template <typename Function>
  343. struct unary_composite : composite<unary_composite<Function> >
  344. {
  345. function compose(actor_list const& elements) const
  346. {
  347. return function(Function(elements.front()));
  348. }
  349. };
  350. ///////////////////////////////////////////////////////////////////////////
  351. // binary_function
  352. ///////////////////////////////////////////////////////////////////////////
  353. template <typename Derived>
  354. struct binary_function : actor<binary_function<Derived> >
  355. {
  356. function a;
  357. function b;
  358. typedef binary_function<Derived> base_type;
  359. binary_function(function const& a, function const& b)
  360. : a(a), b(b)
  361. {
  362. BOOST_ASSERT(!a.empty());
  363. BOOST_ASSERT(!b.empty());
  364. }
  365. utree eval(scope const& env) const
  366. {
  367. return derived().eval(a(env), b(env));
  368. }
  369. Derived const& derived() const
  370. {
  371. return *static_cast<Derived const*>(this);
  372. }
  373. };
  374. template <typename Function>
  375. struct binary_composite : composite<binary_composite<Function> >
  376. {
  377. function compose(actor_list const& elements) const
  378. {
  379. actor_list::const_iterator i = elements.begin();
  380. function a = *i++;
  381. function b = *i;
  382. return function(Function(a, b));
  383. }
  384. };
  385. ///////////////////////////////////////////////////////////////////////////
  386. // nary_function
  387. ///////////////////////////////////////////////////////////////////////////
  388. template <typename Derived>
  389. struct nary_function : actor<nary_function<Derived> >
  390. {
  391. actor_list elements;
  392. typedef nary_function<Derived> base_type;
  393. nary_function(actor_list const& elements)
  394. : elements(elements)
  395. {
  396. BOOST_FOREACH(function const& element, elements)
  397. {
  398. BOOST_ASSERT(!element.empty());
  399. }
  400. }
  401. utree eval(scope const& env) const
  402. {
  403. BOOST_ASSERT(!elements.empty());
  404. actor_list::const_iterator i = elements.begin();
  405. utree result = (*i++)(env);
  406. boost::iterator_range<actor_list::const_iterator>
  407. rest(i++, elements.end());
  408. BOOST_FOREACH(function const& element, rest)
  409. {
  410. if (!derived().eval(result, element(env)))
  411. break; // allow short-circuit evaluation
  412. }
  413. return result;
  414. }
  415. Derived const& derived() const
  416. {
  417. return *static_cast<Derived const*>(this);
  418. }
  419. };
  420. template <typename Function>
  421. struct nary_composite : composite<nary_composite<Function> >
  422. {
  423. function compose(actor_list const& elements) const
  424. {
  425. return function(Function(elements));
  426. }
  427. };
  428. ///////////////////////////////////////////////////////////////////////////
  429. // lambda
  430. ///////////////////////////////////////////////////////////////////////////
  431. struct lambda_function : actor<lambda_function>
  432. {
  433. int level;
  434. actor_list elements;
  435. // we must hold f by reference because functions can be recursive
  436. boost::reference_wrapper<function const> f;
  437. lambda_function(function const& f, actor_list const& elements, int level = 0)
  438. : level(level), elements(elements), f(f) {}
  439. typedef utree result_type;
  440. utree eval(scope const& env) const
  441. {
  442. // Get the parent scope
  443. scope const* outer = &env;
  444. while (level != outer->level())
  445. outer = outer->outer();
  446. if (!elements.empty())
  447. {
  448. boost::scoped_array<utree>
  449. fargs(new utree[elements.size()]);
  450. std::size_t i = 0;
  451. BOOST_FOREACH(function const& element, elements)
  452. {
  453. fargs[i++] = element(env);
  454. }
  455. utree* fi = fargs.get();
  456. return f.get()(scope(fi, fi+elements.size(), outer));
  457. }
  458. else
  459. {
  460. return f.get()(scope(0, 0, outer));
  461. }
  462. }
  463. };
  464. struct lambda : composite<lambda>
  465. {
  466. function f;
  467. lambda() : f() {}
  468. lambda(function const& f) : f(f) {}
  469. function compose(actor_list const& elements) const
  470. {
  471. return function(lambda_function(f, elements));
  472. }
  473. lambda& operator=(lambda const& other)
  474. {
  475. f = other.f;
  476. return *this;
  477. }
  478. lambda& operator=(function const& f_)
  479. {
  480. f = f_;
  481. return *this;
  482. }
  483. };
  484. }
  485. #if defined(BOOST_MSVC)
  486. # pragma warning(pop)
  487. #endif
  488. #endif