$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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;