Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61191 - in trunk/libs/spirit/example/scheme: . detail test
From: joel_at_[hidden]
Date: 2010-04-11 00:48:15


Author: djowel
Date: 2010-04-11 00:48:14 EDT (Sun, 11 Apr 2010)
New Revision: 61191
URL: http://svn.boost.org/trac/boost/changeset/61191

Log:
almost there.
Added:
   trunk/libs/spirit/example/scheme/detail/scheme_function_call.hpp (contents, props changed)
   trunk/libs/spirit/example/scheme/detail/scheme_function_composer_call.hpp (contents, props changed)
Text files modified:
   trunk/libs/spirit/example/scheme/scheme_compiler.hpp | 55 ++++++------
   trunk/libs/spirit/example/scheme/scheme_interpreter.hpp | 179 ++++++++++++++++++++++++++++++++++-----
   trunk/libs/spirit/example/scheme/test/scheme.cpp | 17 +++
   trunk/libs/spirit/example/scheme/utree.hpp | 20 ++--
   4 files changed, 206 insertions(+), 65 deletions(-)

Added: trunk/libs/spirit/example/scheme/detail/scheme_function_call.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/detail/scheme_function_call.hpp 2010-04-11 00:48:14 EDT (Sun, 11 Apr 2010)
@@ -0,0 +1,47 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef SCHEME_FUNCTION_CALL_HPP
+#define SCHEME_FUNCTION_CALL_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+
+#define SCHEME_PUSH_ELEMENT(z, n, _) elements.push_back(_##n);
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (3, BOOST_PP_DEC(SCHEME_COMPOSITE_LIMIT), \
+ "libs/spirit/example/scheme/detail/scheme_function_call.hpp"))
+#include BOOST_PP_ITERATE()
+
+#undef SCHEME_PUSH_ELEMENT
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+ template <BOOST_PP_ENUM_PARAMS(N, typename A)>
+ utree operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& _)) const
+ {
+ utree elements;
+ BOOST_PP_REPEAT(N, SCHEME_PUSH_ELEMENT, _);
+ return f(elements);
+ }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+

Added: trunk/libs/spirit/example/scheme/detail/scheme_function_composer_call.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/detail/scheme_function_composer_call.hpp 2010-04-11 00:48:14 EDT (Sun, 11 Apr 2010)
@@ -0,0 +1,47 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PP_IS_ITERATING
+#ifndef SCHEME_FUNCTION_COMPOSER_CALL_HPP
+#define SCHEME_FUNCTION_COMPOSER_CALL_HPP
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+
+#define SCHEME_PUSH_ELEMENT(z, n, _) elements.push_back(as_function(_##n));
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (3, BOOST_PP_DEC(SCHEME_COMPOSITE_LIMIT), \
+ "libs/spirit/example/scheme/detail/scheme_function_composer_call.hpp"))
+#include BOOST_PP_ITERATE()
+
+#undef SCHEME_PUSH_ELEMENT
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+#else // defined(BOOST_PP_IS_ITERATING)
+
+#define N BOOST_PP_ITERATION()
+
+ template <BOOST_PP_ENUM_PARAMS(N, typename A)>
+ actor operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& _)) const
+ {
+ actor_list elements;
+ BOOST_PP_REPEAT(N, SCHEME_PUSH_ELEMENT, _);
+ return f(elements);
+ }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+

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-11 00:48:14 EDT (Sun, 11 Apr 2010)
@@ -25,8 +25,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 // The compiler
 ///////////////////////////////////////////////////////////////////////////////
- typedef boost::function<function(function_list&)> function_compiler;
-
     class compiler_environment
     {
     public:
@@ -34,16 +32,16 @@
         compiler_environment(compiler_environment* parent = 0)
           : outer(parent) {}
 
- void define(std::string const& name, function_compiler const& def)
+ void define(std::string const& name, function_composer const& def)
         {
             // $$$ use exceptions here $$$
             BOOST_ASSERT(definitions.find(name) == definitions.end());
             definitions[name] = def;
         }
 
- function_compiler* find(std::string const& name)
+ function_composer* find(std::string const& name)
         {
- std::map<std::string, function_compiler>::iterator
+ std::map<std::string, function_composer>::iterator
                 i = definitions.find(name);
             if (i != definitions.end())
                 return &i->second;
@@ -57,14 +55,14 @@
     private:
 
         compiler_environment* outer;
- std::map<std::string, function_compiler> definitions;
+ std::map<std::string, function_composer> definitions;
     };
 
- function compile(utree const& ast, compiler_environment& env);
+ actor compile(utree const& ast, compiler_environment& env);
 
     struct compiler
     {
- typedef function result_type;
+ typedef actor result_type;
 
         mutable compiler_environment& env;
         compiler(compiler_environment& env)
@@ -72,28 +70,27 @@
         {
         }
 
- function operator()(nil) const
+ actor operator()(nil) const
         {
             return scheme::val(utree());
         }
 
         template <typename T>
- function operator()(T const& val) const
+ actor operator()(T const& val) const
         {
             return scheme::val(utree(val));
         }
 
- function operator()(utf8_symbol_range const& str) const
+ actor operator()(utf8_symbol_range const& str) const
         {
             std::string name(str.begin(), str.end());
-
- if (function_compiler* mf = env.find(name))
+ if (function_composer* mf = env.find(name))
             {
- function_list flist;
+ actor_list flist;
                 return (*mf)(flist);
             }
             // $$$ throw? $$$
- return function();
+ return actor();
         }
 
         void define_function(
@@ -103,9 +100,13 @@
         {
             compiler_environment local_env(env);
             for (std::size_t i = 0; i < args.size(); ++i)
- local_env.define(args[i], boost::bind(arg, i));
+ {
+ boost::function<actor(actor_list const&)>
+ f = boost::bind(arg, i);
+ local_env.define(args[i], f);
+ }
             env.define(name,
- function_compiler(call(compile(body, local_env), args.size())));
+ function_composer(call(compile(body, local_env), args.size())));
         }
 
         void define_nullary_function(
@@ -113,11 +114,11 @@
             utree const& body) const
         {
             env.define(name,
- function_compiler(call(compile(body, env), 0)));
+ function_composer(call(compile(body, env), 0)));
         }
 
         template <typename Iterator>
- function operator()(boost::iterator_range<Iterator> const& range) const
+ actor operator()(boost::iterator_range<Iterator> const& range) const
         {
             std::string name(get_symbol(*range.begin()));
 
@@ -141,23 +142,23 @@
                     std::string fname(get_symbol(*i++));
                     define_nullary_function(fname, *i);
                 }
- return function(val(utree(utf8_symbol("<function>"))));
+ return actor(val(utf8_symbol("<function>")));
             }
 
- if (function_compiler* mf = env.find(name))
+ if (function_composer* mf = env.find(name))
             {
- function_list flist;
+ actor_list flist;
                 Iterator i = range.begin(); ++i;
                 for (; i != range.end(); ++i)
                     flist.push_back(compile(*i, env));
                 return (*mf)(flist);
             }
 
- return function(); // $$$ implement me $$$
+ return actor(); // $$$ implement me $$$
         }
     };
 
- function compile(utree const& ast, compiler_environment& env)
+ actor compile(utree const& ast, compiler_environment& env)
     {
         return utree::visit(ast, compiler(env));
     }
@@ -165,18 +166,18 @@
     void compile_all(
         utree const& ast,
         compiler_environment& env,
- function_list& results)
+ actor_list& results)
     {
         BOOST_FOREACH(utree const& program, ast)
         {
- scheme::function f = compile(program, env);
+ scheme::actor f = compile(program, env);
             results.push_back(f);
         }
     }
 
     void build_basic_environment(compiler_environment& env)
     {
- env.define("+", plus_composer());
+ env.define("+", plus);
     }
 }
 

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-11 00:48:14 EDT (Sun, 11 Apr 2010)
@@ -10,6 +10,9 @@
 #include <list>
 #include <boost/function.hpp>
 #include <boost/foreach.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+
+#define SCHEME_COMPOSITE_LIMIT 10
 
 namespace scheme
 {
@@ -17,8 +20,67 @@
 // The runtime interpreter
 ///////////////////////////////////////////////////////////////////////////////
 
- typedef boost::function<utree(utree const& args)> function;
- typedef std::list<function> function_list;
+ ///////////////////////////////////////////////////////////////////////////
+ // actor
+ ///////////////////////////////////////////////////////////////////////////
+ struct actor
+ {
+ typedef utree result_type;
+
+ actor()
+ : f() {}
+
+ actor(boost::function<utree(utree const& args)> const& f)
+ : f(f) {}
+
+ bool empty() const
+ {
+ return f.empty();
+ }
+
+ utree operator()() const
+ {
+ return f(utree());
+ }
+
+ utree operator()(utree const& x) const
+ {
+ if (x.which() == utree_type::list_type)
+ {
+ return f(x);
+ }
+ else
+ {
+ utree elements;
+ elements.push_back(x);
+ return f(elements);
+ }
+ }
+
+ template <typename A0>
+ utree operator()(A0 const& _0) const
+ {
+ utree elements;
+ elements.push_back(_0);
+ return f(elements);
+ }
+
+ template <typename A0, typename A1>
+ utree operator()(A0 const& _0, A1 const& _1) const
+ {
+ utree elements;
+ elements.push_back(_0);
+ elements.push_back(_1);
+ return f(elements);
+ }
+
+ // More operators
+ #include "detail/scheme_function_call.hpp"
+
+ boost::function<utree(utree const& args)> f;
+ };
+
+ typedef std::list<actor> actor_list;
 
     ///////////////////////////////////////////////////////////////////////////
     // values
@@ -37,10 +99,10 @@
 
     struct value_composer
     {
- typedef function result_type;
- function operator()(utree const& val) const
+ typedef actor result_type;
+ actor operator()(utree const& val) const
         {
- return function(value(val));
+ return actor(value(val));
         }
     };
 
@@ -63,29 +125,96 @@
 
     struct argument_composer
     {
- typedef function result_type;
- function operator()(int n) const
+ typedef actor result_type;
+ actor operator()(int n) const
         {
- return function(argument(n));
+ return actor(argument(n));
         }
     };
 
     argument_composer const arg = {};
+ actor const _1 = arg(0);
+ actor const _2 = arg(1);
+ actor const _3 = arg(2);
+ actor const _4 = arg(3);
+ actor const _5 = arg(4);
+ actor const _6 = arg(5);
+ actor const _7 = arg(6);
+ actor const _8 = arg(7);
+ actor const _9 = arg(8);
+ actor const _10 = arg(10);
+
+ ///////////////////////////////////////////////////////////////////////////
+ // function_composer
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ inline actor as_function(T const& val)
+ {
+ return scheme::val(utree(val));
+ }
+
+ inline actor const& as_function(actor const& f)
+ {
+ return f;
+ }
+
+ struct 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();
+ }
+
+ typedef actor result_type;
+
+ actor operator()(actor_list const& elements) const
+ {
+ return f(elements);
+ }
+
+ template <typename A0>
+ actor operator()(A0 const& _0) const
+ {
+ actor_list elements;
+ elements.push_back(as_function(_0));
+ return f(elements);
+ }
+
+ template <typename A0, typename A1>
+ actor operator()(A0 const& _0, A1 const& _1) const
+ {
+ actor_list elements;
+ elements.push_back(as_function(_0));
+ elements.push_back(as_function(_1));
+ return f(elements);
+ }
+
+ // More operators
+ #include "detail/scheme_function_composer_call.hpp"
+ };
 
     ///////////////////////////////////////////////////////////////////////////
     // plus
     ///////////////////////////////////////////////////////////////////////////
     struct plus_function
     {
- function_list elements;
- plus_function(function_list const& elements)
+ actor_list elements;
+ plus_function(actor_list const& elements)
           : elements(elements) {}
 
         typedef utree result_type;
         utree operator()(utree const& args) const
         {
             utree result(0);
- BOOST_FOREACH(function const& element, elements)
+ BOOST_FOREACH(actor const& element, elements)
             {
                 result = result + element(args);
             }
@@ -95,30 +224,30 @@
 
     struct plus_composer
     {
- typedef function result_type;
- function operator()(function_list const& elements)
+ typedef actor result_type;
+ actor operator()(actor_list const& elements) const
         {
- return function(plus_function(elements));
+ return actor(plus_function(elements));
         }
     };
 
- plus_composer const plus = {};
+ function_composer const plus = plus_composer();
 
     ///////////////////////////////////////////////////////////////////////////
     // call
     ///////////////////////////////////////////////////////////////////////////
     struct call_function
     {
- function_list elements;
- function f;
- call_function(function const& f, function_list const& elements)
+ actor_list elements;
+ actor f;
+ call_function(actor const& f, actor_list const& elements)
           : elements(elements), f(f) {}
 
         typedef utree result_type;
         utree operator()(utree const& args) const
         {
             utree fargs;
- BOOST_FOREACH(function const& element, elements)
+ BOOST_FOREACH(actor const& element, elements)
             {
                 fargs.push_back(element(args));
             }
@@ -128,21 +257,21 @@
 
     struct call_composer
     {
- function f;
+ actor f;
         int arity;
- call_composer(function const& f, int arity)
+ call_composer(actor const& f, int arity)
           : f(f), arity(arity) {}
 
- typedef function result_type;
- function operator()(function_list const& elements)
+ typedef actor result_type;
+ actor operator()(actor_list const& elements) const
         {
             // $$$ use throw $$$
             BOOST_ASSERT(elements.size() == arity);
- return function(call_function(f, elements));
+ return actor(call_function(f, elements));
         }
     };
 
- inline call_composer const call(function const& f, int arity)
+ inline function_composer const call(actor const& f, int arity)
     {
         return call_composer(f, arity);
     }

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-11 00:48:14 EDT (Sun, 11 Apr 2010)
@@ -24,6 +24,17 @@
 ///////////////////////////////////////////////////////////////////////////////
 int main(int argc, char **argv)
 {
+ { // testing the c++ side
+
+ using scheme::plus;
+ using scheme::_1;
+ using scheme::_2;
+
+ 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;
+ }
+
     char const* filename = NULL;
     if (argc > 1)
     {
@@ -65,11 +76,11 @@
         std::cout << "success: " << std::endl;
         scheme::compiler_environment env;
         scheme::build_basic_environment(env);
- scheme::function_list flist;
+ scheme::actor_list flist;
         compile_all(program, env, flist);
- BOOST_FOREACH(scheme::function const& f, flist)
+ BOOST_FOREACH(scheme::actor const& f, flist)
         {
- std::cout << " result: " << f(scheme::utree()) << std::endl;
+ std::cout << " result: " << f() << std::endl;
         }
     }
     else

Modified: trunk/libs/spirit/example/scheme/utree.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree.hpp 2010-04-11 00:48:14 EDT (Sun, 11 Apr 2010)
@@ -166,18 +166,18 @@
         typedef boost::iterator_range<const_iterator> const_range;
 
         utree();
- explicit utree(bool b);
- explicit utree(unsigned int i);
- explicit utree(int i);
- explicit utree(double d);
- explicit utree(char const* str);
- explicit utree(char const* str, std::size_t len);
- explicit utree(std::string const& str);
- explicit utree(boost::reference_wrapper<utree> ref);
- explicit utree(function_ptr fptr);
+ utree(bool b);
+ utree(unsigned int i);
+ utree(int i);
+ utree(double d);
+ utree(char const* str);
+ utree(char const* str, std::size_t len);
+ utree(std::string const& str);
+ utree(boost::reference_wrapper<utree> ref);
+ utree(function_ptr fptr);
 
         template <typename Base, utree_type::info type_>
- explicit utree(basic_string<Base, type_> const& bin);
+ utree(basic_string<Base, type_> const& bin);
 
         utree(utree const& other);
         ~utree();


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