|
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