Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61220 - in trunk/libs/spirit/example/scheme: . detail test
From: joel_at_[hidden]
Date: 2010-04-12 04:02:41


Author: djowel
Date: 2010-04-12 04:02:39 EDT (Mon, 12 Apr 2010)
New Revision: 61220
URL: http://svn.boost.org/trac/boost/changeset/61220

Log:
working recursive functions
Text files modified:
   trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp | 7 -
   trunk/libs/spirit/example/scheme/scheme_compiler.hpp | 51 ++++++++++---
   trunk/libs/spirit/example/scheme/scheme_interpreter.hpp | 142 ++++++++++++++++++++++++++++++++++++++-
   trunk/libs/spirit/example/scheme/test/scheme.cpp | 3
   trunk/libs/spirit/example/scheme/test/scheme_test.scm | 4
   trunk/libs/spirit/example/scheme/utree.hpp | 12 +++
   trunk/libs/spirit/example/scheme/utree_operators.hpp | 9 ++
   7 files changed, 201 insertions(+), 27 deletions(-)

Modified: trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp (original)
+++ trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp 2010-04-12 04:02:39 EDT (Mon, 12 Apr 2010)
@@ -7,13 +7,6 @@
 #if !defined(BOOST_SPIRIT_UTREE_DETAIL1)
 #define BOOST_SPIRIT_UTREE_DETAIL1
 
-#if defined(BOOST_MSVC)
-# pragma warning(push)
-# pragma warning(disable: 4804)
-# pragma warning(disable: 4805)
-# pragma warning(disable: 4244)
-#endif
-
 #include <boost/type_traits/alignment_of.hpp>
 
 namespace scheme { namespace detail

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 04:02:39 EDT (Mon, 12 Apr 2010)
@@ -39,6 +39,14 @@
             definitions[name] = def;
         }
 
+ //~ function_composer&
+ //~ forward_declare(std::string const& name)
+ //~ {
+ //~ // $$$ use exceptions here $$$
+ //~ BOOST_ASSERT(definitions.find(name) == definitions.end());
+ //~ return definitions[name];
+ //~ }
+
         function_composer* find(std::string const& name)
         {
             std::map<std::string, function_composer>::iterator
@@ -58,15 +66,16 @@
         std::map<std::string, function_composer> definitions;
     };
 
- actor compile(utree const& ast, environment& env);
+ actor compile(utree const& ast, environment& env, actor_list& fragments);
 
     struct compiler
     {
         typedef actor result_type;
 
- mutable environment& env;
- compiler(environment& env)
- : env(env)
+ environment& env;
+ actor_list& fragments;
+ compiler(environment& env, actor_list& fragments)
+ : env(env), fragments(fragments)
         {
         }
 
@@ -98,23 +107,32 @@
             std::vector<std::string> const& args,
             utree const& body) const
         {
- environment local_env(env);
+ environment local_env(&this->env);
             for (std::size_t i = 0; i < args.size(); ++i)
             {
                 boost::function<actor(actor_list const&)>
                     f = boost::bind(arg, i);
                 local_env.define(args[i], f);
             }
- env.define(name,
- function_composer(lambda(compile(body, local_env), args.size())));
+
+ fragments.push_back(actor());
+ actor& f = fragments.back();
+ env.define(name, lambda(f, args.size()));
+ f = compile(body, local_env, fragments);
+
+
+ //~ function_composer& fc = env.forward_declare(name);
+ //~ fc = lambda(compile(body, local_env), args.size());
         }
 
         void define_nullary_function(
             std::string const& name,
             utree const& body) const
         {
- env.define(name,
- function_composer(lambda(compile(body, env), 0)));
+ fragments.push_back(actor());
+ actor& f = fragments.back();
+ env.define(name, lambda(f, 0));
+ f = compile(body, env, fragments);
         }
 
         template <typename Iterator>
@@ -150,7 +168,7 @@
                 actor_list flist;
                 Iterator i = range.begin(); ++i;
                 for (; i != range.end(); ++i)
- flist.push_back(compile(*i, env));
+ flist.push_back(compile(*i, env, fragments));
                 return (*mf)(flist);
             }
 
@@ -158,26 +176,31 @@
         }
     };
 
- actor compile(utree const& ast, environment& env)
+ actor compile(utree const& ast, environment& env, actor_list& fragments)
     {
- return utree::visit(ast, compiler(env));
+ return utree::visit(ast, compiler(env, fragments));
     }
 
     void compile_all(
         utree const& ast,
         environment& env,
- actor_list& results)
+ actor_list& results,
+ actor_list& fragments)
     {
         BOOST_FOREACH(utree const& program, ast)
         {
- scheme::actor f = compile(program, env);
+ scheme::actor f = compile(program, env, fragments);
             results.push_back(f);
         }
     }
 
     void build_basic_environment(environment& env)
     {
+ env.define("if", if_);
+ env.define("<=", less_than_equal);
         env.define("+", plus);
+ env.define("-", minus);
+ env.define("*", times);
     }
 }
 

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 04:02:39 EDT (Mon, 12 Apr 2010)
@@ -5,7 +5,7 @@
     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 #if !defined(BOOST_SPIRIT_SCHEME_INTERPRETER)
-#define BOOST_SPIRIT_SCHEME_INTERPRETER
+#define BOOST_SPIRIT_SCHEME_INTERPRETER
 
 #include <list>
 #include <boost/function.hpp>
@@ -202,6 +202,71 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
+ // if
+ ///////////////////////////////////////////////////////////////////////////
+ struct if_function
+ {
+ actor cond;
+ actor then;
+ actor else_;
+ if_function(
+ actor const& cond, actor const& then, actor const& else_)
+ : cond(cond), then(then), else_(else_) {}
+
+ typedef utree result_type;
+ utree operator()(utree const& args) const
+ {
+ return cond(args).as<bool>() ? then(args) : else_(args);
+ }
+ };
+
+ struct if_composer
+ {
+ typedef actor result_type;
+ actor operator()(actor_list const& elements) const
+ {
+ actor_list::const_iterator i = elements.begin();
+ actor if_ = *i++;
+ actor then = *i++;
+ actor else_ = *i;
+ return actor(if_function(if_, then, else_));
+ }
+ };
+
+ function_composer const if_ = if_composer();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // less_than_equal
+ ///////////////////////////////////////////////////////////////////////////
+ struct less_than_equal_function
+ {
+ actor a;
+ actor b;
+ less_than_equal_function(actor const& a, actor const& b)
+ : a(a), b(b) {}
+
+ typedef utree result_type;
+ utree operator()(utree const& args) const
+ {
+ return a(args) <= b(args);
+ }
+ };
+
+ struct less_than_equal_composer
+ {
+ typedef actor result_type;
+ actor operator()(actor_list const& elements) const
+ {
+ actor_list::const_iterator i = elements.begin();
+ actor a = *i++;
+ actor b = *i;
+ return actor(less_than_equal_function(a, b));
+ }
+ };
+
+ function_composer const less_than_equal = less_than_equal_composer();
+
+ ///////////////////////////////////////////////////////////////////////////
     // plus
     ///////////////////////////////////////////////////////////////////////////
     struct plus_function
@@ -234,12 +299,80 @@
     function_composer const plus = plus_composer();
 
     ///////////////////////////////////////////////////////////////////////////
+ // minus
+ ///////////////////////////////////////////////////////////////////////////
+ struct minus_function
+ {
+ actor_list elements;
+ minus_function(actor_list const& elements)
+ : elements(elements) {}
+
+ typedef utree result_type;
+ utree operator()(utree const& args) const
+ {
+ actor_list::const_iterator i = elements.begin();
+ utree result = (*i++)(args);
+ boost::iterator_range<actor_list::const_iterator>
+ rest(i++, elements.end());
+ BOOST_FOREACH(actor const& element, rest)
+ {
+ result = result - element(args);
+ }
+ return result;
+ }
+ };
+
+ struct minus_composer
+ {
+ typedef actor result_type;
+ actor operator()(actor_list const& elements) const
+ {
+ return actor(minus_function(elements));
+ }
+ };
+
+ function_composer const minus = minus_composer();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // times
+ ///////////////////////////////////////////////////////////////////////////
+ struct times_function
+ {
+ actor_list elements;
+ times_function(actor_list const& elements)
+ : elements(elements) {}
+
+ typedef utree result_type;
+ utree operator()(utree const& args) const
+ {
+ utree result(1);
+ BOOST_FOREACH(actor const& element, elements)
+ {
+ result = result * element(args);
+ }
+ return result;
+ }
+ };
+
+ struct times_composer
+ {
+ typedef actor result_type;
+ actor operator()(actor_list const& elements) const
+ {
+ return actor(times_function(elements));
+ }
+ };
+
+ function_composer const times = times_composer();
+
+ ///////////////////////////////////////////////////////////////////////////
     // lambda
     ///////////////////////////////////////////////////////////////////////////
     struct lambda_function
     {
         actor_list elements;
- actor f;
+ // we must hold f by reference because functions can be recursive
+ boost::reference_wrapper<actor const> f;
         lambda_function(actor const& f, actor_list const& elements)
           : elements(elements), f(f) {}
 
@@ -251,13 +384,14 @@
             {
                 fargs.push_back(element(args));
             }
- return f(fargs);
+ return f.get()(fargs);
         }
     };
 
     struct lambda_composer
     {
- actor f;
+ // we must hold f by reference because functions can be recursive
+ boost::reference_wrapper<actor const> f;
         int arity;
         lambda_composer(actor const& f, int arity)
           : f(f), arity(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-12 04:02:39 EDT (Mon, 12 Apr 2010)
@@ -77,8 +77,9 @@
         std::cout << "success: " << std::endl;
         scheme::environment env;
         scheme::build_basic_environment(env);
+ scheme::actor_list fragments;
         scheme::actor_list flist;
- compile_all(program, env, flist);
+ compile_all(program, env, flist, fragments);
         BOOST_FOREACH(scheme::actor const& f, flist)
         {
             std::cout << " result: " << f() << std::endl;

Modified: trunk/libs/spirit/example/scheme/test/scheme_test.scm
==============================================================================
--- trunk/libs/spirit/example/scheme/test/scheme_test.scm (original)
+++ trunk/libs/spirit/example/scheme/test/scheme_test.scm 2010-04-12 04:02:39 EDT (Mon, 12 Apr 2010)
@@ -1,3 +1,5 @@
 (define (dbl x) (+ x x))
 (define len 123)
-(dbl len)
\ No newline at end of file
+(dbl len)
+(define (factorial n) (if (<= n 0) 1 (* n (factorial (- n 1)))))
+(factorial 10)
\ No newline at end of file

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-12 04:02:39 EDT (Mon, 12 Apr 2010)
@@ -12,6 +12,13 @@
 #include <string>
 #include <ostream>
 
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4804)
+# pragma warning(disable: 4805)
+# pragma warning(disable: 4244)
+#endif
+
 #include <boost/assert.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/iterator/iterator_facade.hpp>
@@ -297,4 +304,9 @@
 }
 
 #include "detail/utree_detail2.hpp"
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
 #endif

Modified: trunk/libs/spirit/example/scheme/utree_operators.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree_operators.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree_operators.hpp 2010-04-12 04:02:39 EDT (Mon, 12 Apr 2010)
@@ -7,6 +7,11 @@
 #if !defined(BOOST_SPIRIT_UTREE_OPERATORS)
 #define BOOST_SPIRIT_UTREE_OPERATORS
 
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4804)
+#endif
+
 #include "utree.hpp"
 #include <boost/preprocessor/cat.hpp>
 #include <boost/type_traits/is_arithmetic.hpp>
@@ -519,4 +524,8 @@
     }
 }
 
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
 #endif


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