|
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