Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61224 - in trunk/libs/spirit/example/scheme: . detail test
From: joel_at_[hidden]
Date: 2010-04-12 09:25:24


Author: djowel
Date: 2010-04-12 09:25:23 EDT (Mon, 12 Apr 2010)
New Revision: 61224
URL: http://svn.boost.org/trac/boost/changeset/61224

Log:
introduced symmetry with c++ and scheme code
Text files modified:
   trunk/libs/spirit/example/scheme/detail/scheme_function_composer_call.hpp | 2
   trunk/libs/spirit/example/scheme/scheme_compiler.hpp | 19 ++++++++
   trunk/libs/spirit/example/scheme/scheme_interpreter.hpp | 83 +++++++++++++++++++++++++--------------
   trunk/libs/spirit/example/scheme/test/scheme.cpp | 11 +++++
   4 files changed, 81 insertions(+), 34 deletions(-)

Modified: trunk/libs/spirit/example/scheme/detail/scheme_function_composer_call.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/detail/scheme_function_composer_call.hpp (original)
+++ trunk/libs/spirit/example/scheme/detail/scheme_function_composer_call.hpp 2010-04-12 09:25:23 EDT (Mon, 12 Apr 2010)
@@ -38,7 +38,7 @@
     {
         actor_list elements;
         BOOST_PP_REPEAT(N, SCHEME_PUSH_ELEMENT, _);
- return f(elements);
+ return derived()(elements);
     }
 
 #undef N

Modified: trunk/libs/spirit/example/scheme/scheme_compiler.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme_compiler.hpp (original)
+++ trunk/libs/spirit/example/scheme/scheme_compiler.hpp 2010-04-12 09:25:23 EDT (Mon, 12 Apr 2010)
@@ -25,6 +25,21 @@
         return std::string(symbol.begin(), symbol.end());
     }
 
+ struct external_function : composite<external_function>
+ {
+ // we must hold f by reference because functions can be recursive
+ boost::reference_wrapper<actor const> f;
+
+ external_function(actor const& f)
+ : f(f) {}
+
+ using base_type::operator();
+ actor operator()(actor_list const& elements) const
+ {
+ return actor(lambda_function(f, elements));
+ }
+ };
+
 ///////////////////////////////////////////////////////////////////////////////
 // The compiler
 ///////////////////////////////////////////////////////////////////////////////
@@ -112,7 +127,7 @@
 
             fragments.push_back(actor());
             actor& f = fragments.back();
- env.define(name, lambda(f, args.size()));
+ env.define(name, function_composer(external_function(f)));
             f = compile(body, local_env, fragments);
         }
 
@@ -122,7 +137,7 @@
         {
             fragments.push_back(actor());
             actor& f = fragments.back();
- env.define(name, lambda(f, 0));
+ env.define(name, function_composer(external_function(f)));
             f = compile(body, env, fragments);
         }
 

Modified: trunk/libs/spirit/example/scheme/scheme_interpreter.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme_interpreter.hpp (original)
+++ trunk/libs/spirit/example/scheme/scheme_interpreter.hpp 2010-04-12 09:25:23 EDT (Mon, 12 Apr 2010)
@@ -145,7 +145,7 @@
     actor const _10 = arg(10);
 
     ///////////////////////////////////////////////////////////////////////////
- // function_composer
+ // composite
     ///////////////////////////////////////////////////////////////////////////
     template <typename T>
     inline actor as_function(T const& val)
@@ -158,26 +158,15 @@
         return f;
     }
 
- struct function_composer
+ template <typename Derived>
+ struct composite
     {
- boost::function<actor(actor_list const&)> f;
-
- function_composer()
- : f(f) {}
-
- function_composer(boost::function<actor(actor_list const&)> const& f)
- : f(f) {}
-
- bool empty() const
- {
- return f.empty();
- }
-
         typedef actor result_type;
+ typedef composite<Derived> base_type;
 
         actor operator()(actor_list const& elements) const
         {
- return f(elements);
+ return derived()(elements);
         }
 
         template <typename A0>
@@ -185,7 +174,7 @@
         {
             actor_list elements;
             elements.push_back(as_function(_0));
- return f(elements);
+ return derived()(elements);
         }
 
         template <typename A0, typename A1>
@@ -194,11 +183,41 @@
             actor_list elements;
             elements.push_back(as_function(_0));
             elements.push_back(as_function(_1));
- return f(elements);
+ return derived()(elements);
         }
 
         // More operators
         #include "detail/scheme_function_composer_call.hpp"
+
+ Derived const& derived() const
+ {
+ return *static_cast<Derived const*>(this);
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // function_composer
+ ///////////////////////////////////////////////////////////////////////////
+ struct function_composer : composite<function_composer>
+ {
+ boost::function<actor(actor_list const&)> f;
+
+ function_composer()
+ : f(f) {}
+
+ function_composer(boost::function<actor(actor_list const&)> const& f)
+ : f(f) {}
+
+ bool empty() const
+ {
+ return f.empty();
+ }
+
+ using base_type::operator();
+ actor operator()(actor_list const& elements) const
+ {
+ return f(elements);
+ }
     };
 
     ///////////////////////////////////////////////////////////////////////////
@@ -224,27 +243,29 @@
         }
     };
 
- struct lambda_composer
+ struct function : composite<function>
     {
         // we must hold f by reference because functions can be recursive
- boost::reference_wrapper<actor const> f;
- std::size_t arity;
- lambda_composer(actor const& f, std::size_t arity)
- : f(f), arity(arity) {}
+ actor f;
 
- typedef actor result_type;
+ using base_type::operator();
         actor operator()(actor_list const& elements) const
         {
- // $$$ use throw $$$
- BOOST_ASSERT(elements.size() == arity);
             return actor(lambda_function(f, elements));
         }
- };
 
- inline function_composer const lambda(actor const& f, std::size_t arity)
- {
- return function_composer(lambda_composer(f, arity));
- }
+ function& operator=(function const& other)
+ {
+ f = other.f;
+ return *this;
+ }
+
+ function& operator=(actor const& f_)
+ {
+ f = f_;
+ return *this;
+ }
+ };
 }
 
 #endif

Modified: trunk/libs/spirit/example/scheme/test/scheme.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/scheme.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/scheme.cpp 2010-04-12 09:25:23 EDT (Mon, 12 Apr 2010)
@@ -25,14 +25,25 @@
 {
     { // testing the c++ side
 
+ using scheme::if_;
         using scheme::plus;
+ using scheme::times;
+ using scheme::minus;
+ using scheme::lte;
         using scheme::_1;
         using scheme::_2;
+ using scheme::actor;
+ using scheme::function;
 
         std::cout << "result: " << plus(11, 22, 33) () << std::endl;
         std::cout << "result: " << plus(11, 22, _1) (33) << std::endl;
         std::cout << "result: " << plus(11, _1, _2) (22, 33) << std::endl;
         std::cout << "result: " << plus(11, plus(_1, _2)) (22, 33) << std::endl;
+
+ function factorial;
+ factorial = if_(lte(_1, 0), 1, times(_1, factorial(minus(_1, 1))));
+
+ std::cout << "result: " << factorial(_1) (10) << std::endl;
     }
 
     char const* filename = NULL;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk