Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61294 - in trunk/libs/spirit/example/scheme: . input output qi scheme scheme/detail test test/parse_qiexpr test/scheme test/sexpr test/utree utree utree/detail
From: joel_at_[hidden]
Date: 2010-04-15 11:40:41


Author: djowel
Date: 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
New Revision: 61294
URL: http://svn.boost.org/trac/boost/changeset/61294

Log:
Major file reorganization
Added:
   trunk/libs/spirit/example/scheme/scheme/
   trunk/libs/spirit/example/scheme/scheme/compiler.hpp (contents, props changed)
   trunk/libs/spirit/example/scheme/scheme/detail/
   trunk/libs/spirit/example/scheme/scheme/detail/composite_call.hpp (contents, props changed)
   trunk/libs/spirit/example/scheme/scheme/detail/function_call.hpp (contents, props changed)
   trunk/libs/spirit/example/scheme/scheme/interpreter.hpp (contents, props changed)
   trunk/libs/spirit/example/scheme/scheme/intrinsics.hpp (contents, props changed)
   trunk/libs/spirit/example/scheme/test/utree/
   trunk/libs/spirit/example/scheme/test/utree/utree_test.cpp (contents, props changed)
   trunk/libs/spirit/example/scheme/utree/
   trunk/libs/spirit/example/scheme/utree/detail/
   trunk/libs/spirit/example/scheme/utree/detail/utree_detail1.hpp (contents, props changed)
   trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp (contents, props changed)
   trunk/libs/spirit/example/scheme/utree/detail/utree_detail3.hpp (contents, props changed)
   trunk/libs/spirit/example/scheme/utree/io.hpp (contents, props changed)
   trunk/libs/spirit/example/scheme/utree/operators.hpp (contents, props changed)
   trunk/libs/spirit/example/scheme/utree/utree.hpp (contents, props changed)
Removed:
   trunk/libs/spirit/example/scheme/scheme_compiler.hpp
   trunk/libs/spirit/example/scheme/scheme_interpreter.hpp
   trunk/libs/spirit/example/scheme/scheme_intrinsics.hpp
   trunk/libs/spirit/example/scheme/utree.hpp
   trunk/libs/spirit/example/scheme/utree_io.hpp
   trunk/libs/spirit/example/scheme/utree_operators.hpp
Text files modified:
   trunk/libs/spirit/example/scheme/input/parse_sexpr.hpp | 4 +-
   trunk/libs/spirit/example/scheme/input/parse_sexpr_impl.hpp | 4 +-
   trunk/libs/spirit/example/scheme/input/sexpr.hpp | 6 ++--
   trunk/libs/spirit/example/scheme/input/string.hpp | 4 +-
   trunk/libs/spirit/example/scheme/output/generate_sexpr.hpp | 8 +++---
   trunk/libs/spirit/example/scheme/output/generate_sexpr_impl.hpp | 4 +-
   trunk/libs/spirit/example/scheme/output/sexpr.hpp | 12 ++++----
   trunk/libs/spirit/example/scheme/qi/parse_qiexpr.hpp | 2
   trunk/libs/spirit/example/scheme/qi/parse_qiexpr_impl.hpp | 4 +-
   trunk/libs/spirit/example/scheme/qi/qiexpr_parser.hpp | 50 ++++++++++++++++++++--------------------
   trunk/libs/spirit/example/scheme/test/Jamfile | 21 +++++++++++++---
   trunk/libs/spirit/example/scheme/test/parse_qiexpr/generate_sexpr_to_ostream.cpp | 4 +-
   trunk/libs/spirit/example/scheme/test/parse_qiexpr/parse_qi_test.cpp | 6 ++--
   trunk/libs/spirit/example/scheme/test/parse_qiexpr/parse_qiexpr.cpp | 4 +-
   trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp | 6 ++--
   trunk/libs/spirit/example/scheme/test/scheme/scheme_test2.cpp | 4 +-
   trunk/libs/spirit/example/scheme/test/scheme/scheme_test3.cpp | 8 +++---
   trunk/libs/spirit/example/scheme/test/sexpr/sexpr_input_test.cpp | 6 ++--
   trunk/libs/spirit/example/scheme/test/sexpr/sexpr_output_test.cpp | 4 +-
   19 files changed, 87 insertions(+), 74 deletions(-)

Modified: trunk/libs/spirit/example/scheme/input/parse_sexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/input/parse_sexpr.hpp (original)
+++ trunk/libs/spirit/example/scheme/input/parse_sexpr.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -7,8 +7,8 @@
 #if !defined(BOOST_SPIRIT_PARSE_SEXPR)
 #define BOOST_SPIRIT_PARSE_SEXPR
 
-#include "../utree.hpp"
-#include "../input/sexpr.hpp"
+#include <utree/utree.hpp>
+#include <input/sexpr.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/type_traits/is_base_of.hpp>
 #include <iosfwd>

Modified: trunk/libs/spirit/example/scheme/input/parse_sexpr_impl.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/input/parse_sexpr_impl.hpp (original)
+++ trunk/libs/spirit/example/scheme/input/parse_sexpr_impl.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -12,8 +12,8 @@
 #include <boost/spirit/include/support_istream_iterator.hpp>
 #include <boost/spirit/include/qi_parse.hpp>
 
-#include "../input/sexpr.hpp"
-#include "../input/parse_sexpr.hpp"
+#include <input/sexpr.hpp>
+#include <input/parse_sexpr.hpp>
 
 namespace scheme { namespace input
 {

Modified: trunk/libs/spirit/example/scheme/input/sexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/input/sexpr.hpp (original)
+++ trunk/libs/spirit/example/scheme/input/sexpr.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -17,9 +17,9 @@
 #include <boost/spirit/include/phoenix_operator.hpp>
 #include <boost/regex/pending/unicode_iterator.hpp>
 
-#include "../utree.hpp"
-#include "../utree_operators.hpp"
-#include "string.hpp"
+#include <utree/utree.hpp>
+#include <utree/operators.hpp>
+#include <input/string.hpp>
 
 namespace scheme { namespace input
 {

Modified: trunk/libs/spirit/example/scheme/input/string.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/input/string.hpp (original)
+++ trunk/libs/spirit/example/scheme/input/string.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -17,8 +17,8 @@
 #include <boost/spirit/include/phoenix_operator.hpp>
 #include <boost/regex/pending/unicode_iterator.hpp>
 
-#include "../utree.hpp"
-#include "../utree_operators.hpp"
+#include <utree/utree.hpp>
+#include <utree/operators.hpp>
 
 namespace scheme { namespace input
 {

Modified: trunk/libs/spirit/example/scheme/output/generate_sexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/output/generate_sexpr.hpp (original)
+++ trunk/libs/spirit/example/scheme/output/generate_sexpr.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -1,13 +1,13 @@
 // Copyright (c) 2001-2010 Hartmut Kaiser
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+//
+// 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)
 
 #if !defined(SCHEME_OUTPUT_GENERATE_SEXPR_MAR_29_2010_1210PM)
 #define SCHEME_OUTPUT_GENERATE_SEXPR_MAR_29_2010_1210PM
 
-#include "../utree.hpp"
-#include "../output/sexpr.hpp"
+#include <utree/utree.hpp>
+#include <output/sexpr.hpp>
 
 namespace scheme { namespace output
 {

Modified: trunk/libs/spirit/example/scheme/output/generate_sexpr_impl.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/output/generate_sexpr_impl.hpp (original)
+++ trunk/libs/spirit/example/scheme/output/generate_sexpr_impl.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -11,8 +11,8 @@
 #include <boost/spirit/include/karma_list.hpp>
 #include <boost/spirit/include/support_ostream_iterator.hpp>
 
-#include "../output/sexpr.hpp"
-#include "../output/generate_sexpr.hpp"
+#include <output/sexpr.hpp>
+#include <output/generate_sexpr.hpp>
 
 namespace scheme { namespace output
 {

Modified: trunk/libs/spirit/example/scheme/output/sexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/output/sexpr.hpp (original)
+++ trunk/libs/spirit/example/scheme/output/sexpr.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -1,13 +1,13 @@
 // Copyright (c) 2001-2010 Hartmut Kaiser
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+//
+// 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)
 
 #if !defined(SCHEME_OUTPUT_SEXPR_MAR_8_2010_829AM)
 #define SCHEME_OUTPUT_SEXPR_MAR_8_2010_829AM
 
-#include "../utree.hpp"
-#include "../detail/utree_detail3.hpp"
+#include <utree/utree.hpp>
+#include <utree/detail/utree_detail3.hpp>
 
 #include <string>
 
@@ -18,13 +18,13 @@
 ///////////////////////////////////////////////////////////////////////////////
 namespace boost { namespace spirit { namespace traits
 {
- // the specialization below tells Spirit to handle scheme::utree as if it
+ // the specialization below tells Spirit to handle scheme::utree as if it
     // where a 'real' variant (in the context of karma)
     template <>
     struct not_is_variant<scheme::utree, karma::domain>
       : mpl::false_ {};
 
- // The specializations below tell Spirit to verify whether an attribute
+ // The specializations below tell Spirit to verify whether an attribute
     // type is compatible with a given variant type
     template <>
     struct compute_compatible_component_variant<

Modified: trunk/libs/spirit/example/scheme/qi/parse_qiexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/qi/parse_qiexpr.hpp (original)
+++ trunk/libs/spirit/example/scheme/qi/parse_qiexpr.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -6,7 +6,7 @@
 #if !defined(BOOST_SPIRIT_PARSE_QIEXPR)
 #define BOOST_SPIRIT_PARSE_QIEXPR
 
-#include "../utree.hpp"
+#include <utree/utree.hpp>
 
 namespace scheme { namespace input
 {

Modified: trunk/libs/spirit/example/scheme/qi/parse_qiexpr_impl.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/qi/parse_qiexpr_impl.hpp (original)
+++ trunk/libs/spirit/example/scheme/qi/parse_qiexpr_impl.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -10,8 +10,8 @@
 #include <boost/spirit/include/support_istream_iterator.hpp>
 #include <boost/spirit/include/qi_parse.hpp>
 
-#include "../qi/qiexpr_parser.hpp"
-#include "../qi/parse_qiexpr.hpp"
+#include <qi/qiexpr_parser.hpp>
+#include <qi/parse_qiexpr.hpp>
 
 namespace scheme { namespace input
 {

Modified: trunk/libs/spirit/example/scheme/qi/qiexpr_parser.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/qi/qiexpr_parser.hpp (original)
+++ trunk/libs/spirit/example/scheme/qi/qiexpr_parser.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -1,6 +1,6 @@
 // Copyright (c) 2001-2010 Hartmut Kaiser
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+//
+// 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)
 
 #if !defined(BOOST_SPIRIT_QIEXPR_PARSER)
@@ -16,10 +16,10 @@
 #include <boost/spirit/include/phoenix_statement.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>
 
-#include "../utree.hpp"
-#include "../detail/utree_detail3.hpp"
-#include "../utree_operators.hpp"
-#include "../input/string.hpp"
+#include <utree/utree.hpp>
+#include <utree/detail/utree_detail3.hpp>
+#include <utree_operators.hpp>
+#include <input/string.hpp>
 
 namespace boost { namespace spirit { namespace traits
 {
@@ -27,7 +27,7 @@
 }}}
 
 ///////////////////////////////////////////////////////////////////////////////
-namespace scheme { namespace qi
+namespace scheme { namespace qi
 {
     using boost::spirit::ascii::space;
     using boost::spirit::ascii::char_;
@@ -60,7 +60,7 @@
     namespace detail
     {
         ///////////////////////////////////////////////////////////////////////
- // return true if the utree instance represents a list whose first
+ // return true if the utree instance represents a list whose first
         // element is a symbol node equal to the second argument
         inline bool is_list_node(utree const& u, utf8_symbol const& symbol)
         {
@@ -79,7 +79,7 @@
         }
 
         ///////////////////////////////////////////////////////////////////////
- // ensure the given utree instance represents a list whose first
+ // ensure the given utree instance represents a list whose first
         // element is the symbol this function object has been constructed from
         struct make_list_node
         {
@@ -90,21 +90,21 @@
               : symbol(symbol_)
             {}
 
- // If called with one parameter the given node needs to be
+ // If called with one parameter the given node needs to be
             // converted into a list whose first element is the symbol.
             //
- // i.e:
+ // i.e:
             // lit: ("abc") --> (lit "abc")
             void operator()(utree& u) const
             {
                 u.push_front(symbol);
             }
 
- // If called with two parameters we ensure the given node is a
- // (new) list whose first element is the symbol and we append the
+ // If called with two parameters we ensure the given node is a
+ // (new) list whose first element is the symbol and we append the
             // given element to that list.
             //
- // i.e.:
+ // i.e.:
             // >>: (char_), (char_ "abc") --> (>> (char_) (char_ "abc"))
             // >>: (>> (char_ "a")), (char_) --> (>> (char_ "a") (char_))
             void operator()(utree& val, utree const& element) const
@@ -137,7 +137,7 @@
 
     ///////////////////////////////////////////////////////////////////////////
     // a list of names for all supported parser primitives taking no parameters
- static char const* const primitives0[] =
+ static char const* const primitives0[] =
     {
       // character parsers
         "char_"
@@ -163,7 +163,7 @@
     };
 
     // a list of names for all supported parser primitives taking 1 parameter
- static char const* const primitives1[] =
+ static char const* const primitives1[] =
     {
         // character parsers
         "char_", "lit", "string"
@@ -171,14 +171,14 @@
     };
 
     // a list of names for all supported parser primitives taking 2 parameter
- static char const* const primitives2[] =
+ static char const* const primitives2[] =
     {
         "char_"
       , 0
     };
 
     // a list of names for all supported parser directives taking 0 parameter
- static char const* const directives0[] =
+ static char const* const directives0[] =
     {
         // manage skip parser
         "lexeme", "skip", "no_skip"
@@ -196,10 +196,10 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Iterator>
- struct qiexpr_parser
+ struct qiexpr_parser
       : grammar<Iterator, qiexpr_white_space<Iterator>, utree()>
     {
- typedef typename boost::detail::iterator_traits<Iterator>::value_type
+ typedef typename boost::detail::iterator_traits<Iterator>::value_type
             char_type;
 
         qiexpr_parser() : qiexpr_parser::base_type(start)
@@ -229,19 +229,19 @@
                 ;
 
             // A ^ B
- permutation =
+ permutation =
                     sequence [ _val = _1 ]
>> *( "^" >> sequence [ make_permutation(_val, _1) ] )
                 ;
 
             // A >> B
- sequence =
+ sequence =
                     unary_term [ _val = _1 ]
>> *( ">>" >> unary_term [ make_sequence(_val, _1) ] )
                 ;
 
             // unary operators
- unary_term =
+ unary_term =
                     '*' >> term [ make_kleene(_val, _1) ]
                 | '+' >> term [ make_plus(_val, _1) ]
                 | '-' >> term [ make_optional(_val, _1) ]
@@ -257,7 +257,7 @@
                 | '(' >> alternative >> ')'
                 ;
 
- // any parser directive
+ // any parser directive
             directive =
                     (directive0 >> '[' >> alternative >> ']')
                     [
@@ -274,7 +274,7 @@
                 ;
 
             // a literal (either 'x' or "abc")
- literal =
+ literal =
                     string_lit [ push_back(_val, _1) ]
                 | string_lit.char_lit [ push_back(_val, _1) ]
                 ;

Added: trunk/libs/spirit/example/scheme/scheme/compiler.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/scheme/compiler.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -0,0 +1,261 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_SCHEME_COMPILER)
+#define BOOST_SPIRIT_SCHEME_COMPILER
+
+#include <vector>
+#include <map>
+#include <boost/bind.hpp>
+
+#include <scheme/intrinsics.hpp>
+#include <scheme/interpreter.hpp>
+#include <input/parse_sexpr.hpp>
+
+namespace scheme
+{
+///////////////////////////////////////////////////////////////////////////////
+// The environment
+///////////////////////////////////////////////////////////////////////////////
+ typedef boost::function<function(actor_list const&)> compiled_function;
+
+ class environment
+ {
+ public:
+
+ environment(environment* parent = 0)
+ : outer(parent) {}
+
+ template <typename Function>
+ void define(std::string const& name, Function const& f)
+ {
+ // $$$ use exceptions here? $$$
+ BOOST_ASSERT(definitions.find(name) == definitions.end());
+ definitions[name] = compiled_function(f);
+ }
+
+ compiled_function* find(std::string const& name)
+ {
+ std::map<std::string, compiled_function>::iterator
+ i = definitions.find(name);
+ if (i != definitions.end())
+ return &i->second;
+ else if (outer != 0)
+ return outer->find(name);
+ return 0;
+ }
+
+ environment* parent() const { return outer; }
+
+ private:
+
+ environment* outer;
+ std::map<std::string, compiled_function> definitions;
+ };
+
+///////////////////////////////////////////////////////////////////////////////
+// The compiler
+///////////////////////////////////////////////////////////////////////////////
+ function compile(
+ utree const& ast, environment& env, actor_list& fragments);
+
+ struct external_function : composite<external_function>
+ {
+ // we must hold f by reference because functions can be recursive
+ boost::reference_wrapper<function const> f;
+
+ external_function(function const& f)
+ : f(f) {}
+
+ using base_type::operator();
+ function operator()(actor_list const& elements) const
+ {
+ return function(lambda_function(f, elements));
+ }
+ };
+
+ struct compiler
+ {
+ typedef function result_type;
+ environment& env;
+ actor_list& fragments;
+
+ compiler(environment& env, actor_list& fragments)
+ : env(env), fragments(fragments)
+ {
+ }
+
+ function operator()(nil) const
+ {
+ return scheme::val(utree());
+ }
+
+ template <typename T>
+ function operator()(T const& val) const
+ {
+ return scheme::val(utree(val));
+ }
+
+ function operator()(utf8_symbol_range const& str) const
+ {
+ std::string name(str.begin(), str.end());
+ if (compiled_function* mf = env.find(name))
+ {
+ actor_list flist;
+ return (*mf)(flist);
+ }
+ // $$$ throw? $$$
+ BOOST_ASSERT(false);
+ return function();
+ }
+
+ function make_lambda(
+ std::vector<std::string> const& args,
+ utree const& body) const
+ {
+ environment local_env(&this->env);
+ for (std::size_t i = 0; i < args.size(); ++i)
+ local_env.define(args[i], boost::bind(arg, i));
+ return compile(body, local_env, fragments);
+ }
+
+ function define_function(
+ std::string const& name,
+ std::vector<std::string> const& args,
+ utree const& body) const
+ {
+ fragments.push_back(function());
+ function& f = fragments.back();
+ env.define(name, external_function(f));
+ f = make_lambda(args, body);
+ return f;
+ }
+
+ template <typename Iterator>
+ function operator()(boost::iterator_range<Iterator> const& range) const
+ {
+ std::string name(get_symbol(*range.begin()));
+
+ if (name == "define")
+ {
+ std::string fname;
+ std::vector<std::string> args;
+
+ Iterator i = range.begin(); ++i;
+ if (i->which() == utree_type::list_type)
+ {
+ // (define (f x) ...body...)
+ utree const& decl = *i++;
+ Iterator di = decl.begin();
+ fname = get_symbol(*di++);
+ while (di != decl.end())
+ args.push_back(get_symbol(*di++));
+ }
+ else
+ {
+ // (define f ...body...)
+ fname = get_symbol(*i++);
+ }
+
+ return define_function(fname, args, *i);
+ }
+
+ if (name == "lambda")
+ {
+ // (lambda (x) ...body...)
+ Iterator i = range.begin(); ++i;
+ utree const& arg_names = *i++;
+ Iterator ai = arg_names.begin();
+ std::vector<std::string> args;
+ while (ai != arg_names.end())
+ args.push_back(get_symbol(*ai++));
+ return make_lambda(args, *i);
+ }
+
+ if (compiled_function* mf = env.find(name))
+ {
+ actor_list flist;
+ Iterator i = range.begin(); ++i;
+ for (; i != range.end(); ++i)
+ flist.push_back(compile(*i, env, fragments));
+ return (*mf)(flist);
+ }
+
+ BOOST_ASSERT(false);
+ return function(); // $$$ implement me $$$
+ }
+
+ static std::string get_symbol(utree const& s)
+ {
+ utf8_symbol_range symbol = s.as<utf8_symbol_range>();
+ return std::string(symbol.begin(), symbol.end());
+ }
+ };
+
+ inline function compile(
+ utree const& ast, environment& env, actor_list& fragments)
+ {
+ return utree::visit(ast, compiler(env, fragments));
+ }
+
+ void compile_all(
+ utree const& ast,
+ environment& env,
+ actor_list& results,
+ actor_list& fragments)
+ {
+ BOOST_FOREACH(utree const& program, ast)
+ {
+ scheme::function f = compile(program, env, fragments);
+ results.push_back(f);
+ }
+ }
+
+ void build_basic_environment(environment& env)
+ {
+ env.define("if", if_);
+ env.define("<", less_than);
+ env.define("<=", less_than_equal);
+ env.define("+", plus);
+ env.define("-", minus);
+ env.define("*", times);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // interpreter
+ ///////////////////////////////////////////////////////////////////////////
+ struct interpreter : actor<interpreter>
+ {
+ template <typename Source>
+ interpreter(Source& in, environment* outer = 0)
+ {
+ if (outer == 0)
+ build_basic_environment(env);
+
+ if (input::parse_sexpr_list(in, program))
+ {
+ compile_all(program, env, flist, fragments);
+ }
+ else
+ {
+ // $$$ Use exceptions $$$
+ BOOST_ASSERT(false);
+ }
+ }
+
+ utree eval(args_type args) const
+ {
+ return flist.back()(args);
+ }
+
+ environment env;
+ utree program;
+ actor_list fragments;
+ actor_list flist;
+ };
+}
+
+#endif

Added: trunk/libs/spirit/example/scheme/scheme/detail/composite_call.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/scheme/detail/composite_call.hpp 2010-04-15 11:40:37 EDT (Thu, 15 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), \
+ "scheme/detail/composite_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)>
+ function operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& _)) const
+ {
+ actor_list elements;
+ BOOST_PP_REPEAT(N, SCHEME_PUSH_ELEMENT, _);
+ return derived()(elements);
+ }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+

Added: trunk/libs/spirit/example/scheme/scheme/detail/function_call.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/scheme/detail/function_call.hpp 2010-04-15 11:40:37 EDT (Thu, 15 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[n] = _##n;
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (3, BOOST_PP_DEC(SCHEME_COMPOSITE_LIMIT), \
+ "scheme/detail/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
+ {
+ boost::array<utree, N> elements;
+ BOOST_PP_REPEAT(N, SCHEME_PUSH_ELEMENT, _);
+ return derived()(get_range(elements));
+ }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
+

Added: trunk/libs/spirit/example/scheme/scheme/interpreter.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/scheme/interpreter.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -0,0 +1,406 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_SCHEME_INTERPRETER)
+#define BOOST_SPIRIT_SCHEME_INTERPRETER
+
+#include <list>
+#include <boost/function.hpp>
+#include <boost/foreach.hpp>
+#include <boost/array.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <utree/utree.hpp>
+
+#define SCHEME_COMPOSITE_LIMIT 10
+
+namespace scheme
+{
+///////////////////////////////////////////////////////////////////////////////
+// The runtime interpreter
+///////////////////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////////////
+ // typedefs
+ ///////////////////////////////////////////////////////////////////////////
+ struct function;
+
+ typedef std::list<function> actor_list;
+ typedef boost::iterator_range<utree const*> args_type;
+ typedef boost::function<utree(args_type args)> stored_function;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // actor
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Derived>
+ struct actor
+ {
+ typedef utree result_type;
+ typedef actor<Derived> base_type;
+
+ utree operator()(args_type args) const
+ {
+ return derived().eval(args);
+ }
+
+ utree operator()() const
+ {
+ return derived().eval(args_type());
+ }
+
+ template <typename A0>
+ utree operator()(A0 const& _0) const
+ {
+ boost::array<utree, 1> elements;
+ elements[0] = _0;
+ return derived().eval(get_range(elements));
+ }
+
+ template <typename A0, typename A1>
+ utree operator()(A0 const& _0, A1 const& _1) const
+ {
+ boost::array<utree, 2> elements;
+ elements[0] = _0;
+ elements[1] = _1;
+ return derived().eval(get_range(elements));
+ }
+
+ // More operators
+ #include <scheme/detail/function_call.hpp>
+
+ template <std::size_t n>
+ static args_type
+ get_range(boost::array<utree, n> const& array)
+ {
+ return args_type(array.begin(), array.end());
+ }
+
+ Derived const& derived() const
+ {
+ return *static_cast<Derived const*>(this);
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // function
+ ///////////////////////////////////////////////////////////////////////////
+ struct function : actor<function>
+ {
+ stored_function f;
+ function()
+ : f() {}
+
+ function(stored_function const& f)
+ : f(f)
+ {
+ BOOST_ASSERT(!f.empty());
+ }
+
+ bool empty() const
+ {
+ return f.empty();
+ }
+
+ utree eval(args_type args) const
+ {
+ return f(args);
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // values
+ ///////////////////////////////////////////////////////////////////////////
+ struct value_function : actor<value_function>
+ {
+ utree val;
+ value_function(utree const& val) : val(val) {}
+
+ utree eval(args_type /*args*/) const
+ {
+ return utree(boost::ref(val));
+ }
+ };
+
+ struct value
+ {
+ typedef function result_type;
+ function operator()(utree const& val) const
+ {
+ return function(value_function(val));
+ }
+ };
+
+ value const val = {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // arguments
+ ///////////////////////////////////////////////////////////////////////////
+ struct argument_function : actor<argument_function>
+ {
+ std::size_t n;
+ argument_function(std::size_t n) : n(n) {}
+
+ utree eval(args_type args) const
+ {
+ return utree(boost::ref(args[n]));
+ }
+ };
+
+ struct argument
+ {
+ typedef function result_type;
+ function operator()(std::size_t n) const
+ {
+ return function(argument_function(n));
+ }
+ };
+
+ argument const arg = {};
+ function const _1 = arg(0);
+ function const _2 = arg(1);
+ function const _3 = arg(2);
+ function const _4 = arg(3);
+ function const _5 = arg(4);
+ function const _6 = arg(5);
+ function const _7 = arg(6);
+ function const _8 = arg(7);
+ function const _9 = arg(8);
+ function const _10 = arg(10);
+
+ ///////////////////////////////////////////////////////////////////////////
+ // composite
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Derived>
+ struct composite
+ {
+ typedef function result_type;
+ typedef composite<Derived> base_type;
+
+ function operator()(actor_list const& elements) const
+ {
+ return derived().compose(elements);
+ }
+
+ template <typename A0>
+ function operator()(A0 const& _0) const
+ {
+ actor_list elements;
+ elements.push_back(as_function(_0));
+ return derived().compose(elements);
+ }
+
+ template <typename A0, typename A1>
+ function operator()(A0 const& _0, A1 const& _1) const
+ {
+ actor_list elements;
+ elements.push_back(as_function(_0));
+ elements.push_back(as_function(_1));
+ return derived().compose(elements);
+ }
+
+ // More operators
+ #include <scheme/detail/composite_call.hpp>
+
+ Derived const& derived() const
+ {
+ return *static_cast<Derived const*>(this);
+ }
+
+ template <typename T>
+ static function as_function(T const& val)
+ {
+ return scheme::val(utree(val));
+ }
+
+ static function const& as_function(function const& f)
+ {
+ return f;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // unary_function
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Derived>
+ struct unary_function : actor<unary_function<Derived> >
+ {
+ function a;
+ typedef unary_function<Derived> base_type;
+
+ unary_function(function const& a)
+ : a(a)
+ {
+ BOOST_ASSERT(!a.empty());
+ }
+
+ utree eval(args_type args) const
+ {
+ return derived().eval(a(args));
+ }
+
+ Derived const& derived() const
+ {
+ return *static_cast<Derived const*>(this);
+ }
+ };
+
+ template <typename Function>
+ struct unary_composite : composite<unary_composite<Function> >
+ {
+ function compose(actor_list const& elements) const
+ {
+ return function(Function(elements.front()));
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // binary_function
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Derived>
+ struct binary_function : actor<binary_function<Derived> >
+ {
+ function a;
+ function b;
+ typedef binary_function<Derived> base_type;
+
+ binary_function(function const& a, function const& b)
+ : a(a), b(b)
+ {
+ BOOST_ASSERT(!a.empty());
+ BOOST_ASSERT(!b.empty());
+ }
+
+ utree eval(args_type args) const
+ {
+ return derived().eval(a(args), b(args));
+ }
+
+ Derived const& derived() const
+ {
+ return *static_cast<Derived const*>(this);
+ }
+ };
+
+ template <typename Function>
+ struct binary_composite : composite<binary_composite<Function> >
+ {
+ function compose(actor_list const& elements) const
+ {
+ actor_list::const_iterator i = elements.begin();
+ function a = *i++;
+ function b = *i;
+ return function(Function(a, b));
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // nary_function
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Derived>
+ struct nary_function : actor<nary_function<Derived> >
+ {
+ actor_list elements;
+ typedef nary_function<Derived> base_type;
+
+ nary_function(actor_list const& elements)
+ : elements(elements)
+ {
+ BOOST_FOREACH(function const& element, elements)
+ {
+ BOOST_ASSERT(!element.empty());
+ }
+ }
+
+ utree eval(args_type 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(function const& element, rest)
+ {
+ if (!derived().eval(result, element(args)))
+ break; // allow short-circuit evaluation
+ }
+ return result;
+ }
+
+ Derived const& derived() const
+ {
+ return *static_cast<Derived const*>(this);
+ }
+ };
+
+ template <typename Function>
+ struct nary_composite : composite<nary_composite<Function> >
+ {
+ function compose(actor_list const& elements) const
+ {
+ return function(Function(elements));
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // lambda
+ ///////////////////////////////////////////////////////////////////////////
+ struct lambda_function : actor<lambda_function>
+ {
+ actor_list elements;
+ // we must hold f by reference because functions can be recursive
+ boost::reference_wrapper<function const> f;
+
+ lambda_function(function const& f, actor_list const& elements)
+ : elements(elements), f(f) {}
+
+ typedef utree result_type;
+ utree eval(args_type args) const
+ {
+ if (!elements.empty())
+ {
+ boost::scoped_array<utree>
+ fargs(new utree[elements.size()]);
+ std::size_t i = 0;
+ BOOST_FOREACH(function const& element, elements)
+ {
+ fargs[i++] = element(args);
+ }
+ utree const* fi = fargs.get();
+ return f.get()(args_type(fi, fi+elements.size()));
+ }
+ else
+ {
+ return f.get()();
+ }
+ }
+ };
+
+ struct lambda : composite<lambda>
+ {
+ function f;
+
+ lambda() : f() {}
+ lambda(function const& f) : f(f) {}
+
+ function compose(actor_list const& elements) const
+ {
+ return function(lambda_function(f, elements));
+ }
+
+ lambda& operator=(lambda const& other)
+ {
+ f = other.f;
+ return *this;
+ }
+
+ lambda& operator=(function const& f_)
+ {
+ f = f_;
+ return *this;
+ }
+ };
+}
+
+#endif

Added: trunk/libs/spirit/example/scheme/scheme/intrinsics.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/scheme/intrinsics.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -0,0 +1,154 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_SCHEME_INTRINSICS)
+#define BOOST_SPIRIT_SCHEME_INTRINSICS
+
+#include <scheme/interpreter.hpp>
+#include <utree/operators.hpp>
+
+namespace scheme
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // if
+ ///////////////////////////////////////////////////////////////////////////
+ struct if_function : actor<if_function>
+ {
+ function cond;
+ function then;
+ function else_;
+ if_function(
+ function const& cond, function const& then, function const& else_)
+ : cond(cond), then(then), else_(else_)
+ {
+ BOOST_ASSERT(!cond.empty());
+ BOOST_ASSERT(!then.empty());
+ BOOST_ASSERT(!else_.empty());
+ }
+
+ typedef utree result_type;
+ utree eval(args_type args) const
+ {
+ return cond(args).as<bool>() ? then(args) : else_(args);
+ }
+ };
+
+ struct if_composite : composite<if_composite>
+ {
+ function compose(actor_list const& elements) const
+ {
+ actor_list::const_iterator i = elements.begin();
+ function if_ = *i++;
+ function then = *i++;
+ function else_ = *i;
+ return function(if_function(if_, then, else_));
+ }
+ };
+
+ if_composite const if_ = if_composite();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // less_than
+ ///////////////////////////////////////////////////////////////////////////
+ struct less_than_function
+ : binary_function<less_than_function>
+ {
+ less_than_function(function const& a, function const& b)
+ : base_type(a, b) {}
+
+ typedef utree result_type;
+ utree eval(utree const& a, utree const& b) const
+ {
+ return a < b;
+ }
+ };
+
+ struct less_than_composite
+ : binary_composite<less_than_function> {};
+
+ less_than_composite const less_than
+ = less_than_composite();
+ less_than_composite const lt = less_than; // synonym
+
+ ///////////////////////////////////////////////////////////////////////////
+ // less_than_equal
+ ///////////////////////////////////////////////////////////////////////////
+ struct less_than_equal_function
+ : binary_function<less_than_equal_function>
+ {
+ less_than_equal_function(function const& a, function const& b)
+ : base_type(a, b) {}
+
+ typedef utree result_type;
+ utree eval(utree const& a, utree const& b) const
+ {
+ return a <= b;
+ }
+ };
+
+ struct less_than_equal_composite
+ : binary_composite<less_than_equal_function> {};
+
+ less_than_equal_composite const less_than_equal
+ = less_than_equal_composite();
+ less_than_equal_composite const lte = less_than_equal; // synonym
+
+ ///////////////////////////////////////////////////////////////////////////
+ // plus
+ ///////////////////////////////////////////////////////////////////////////
+ struct plus_function : nary_function<plus_function>
+ {
+ plus_function(actor_list const& elements)
+ : base_type(elements) {}
+
+ bool eval(utree& result, utree const& element) const
+ {
+ result = result + element;
+ return true;
+ }
+ };
+
+ struct plus_composite : nary_composite<plus_function> {};
+ plus_composite const plus = plus_composite();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // minus
+ ///////////////////////////////////////////////////////////////////////////
+ struct minus_function : nary_function<minus_function>
+ {
+ minus_function(actor_list const& elements)
+ : base_type(elements) {}
+
+ bool eval(utree& result, utree const& element) const
+ {
+ result = result - element;
+ return true;
+ }
+ };
+
+ struct minus_composite : nary_composite<minus_function> {};
+ minus_composite const minus = minus_composite();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // times
+ ///////////////////////////////////////////////////////////////////////////
+ struct times_function : nary_function<times_function>
+ {
+ times_function(actor_list const& elements)
+ : base_type(elements) {}
+
+ bool eval(utree& result, utree const& element) const
+ {
+ result = result * element;
+ return true;
+ }
+ };
+
+ struct times_composite : nary_composite<times_function> {};
+ times_composite const times = times_composite();
+}
+
+#endif

Deleted: trunk/libs/spirit/example/scheme/scheme_compiler.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme_compiler.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
+++ (empty file)
@@ -1,261 +0,0 @@
-/*=============================================================================
- 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)
-=============================================================================*/
-#if !defined(BOOST_SPIRIT_SCHEME_COMPILER)
-#define BOOST_SPIRIT_SCHEME_COMPILER
-
-#include <vector>
-#include <map>
-#include <boost/bind.hpp>
-
-#include "scheme_intrinsics.hpp"
-#include "scheme_interpreter.hpp"
-#include "input/parse_sexpr.hpp"
-
-namespace scheme
-{
-///////////////////////////////////////////////////////////////////////////////
-// The environment
-///////////////////////////////////////////////////////////////////////////////
- typedef boost::function<function(actor_list const&)> compiled_function;
-
- class environment
- {
- public:
-
- environment(environment* parent = 0)
- : outer(parent) {}
-
- template <typename Function>
- void define(std::string const& name, Function const& f)
- {
- // $$$ use exceptions here? $$$
- BOOST_ASSERT(definitions.find(name) == definitions.end());
- definitions[name] = compiled_function(f);
- }
-
- compiled_function* find(std::string const& name)
- {
- std::map<std::string, compiled_function>::iterator
- i = definitions.find(name);
- if (i != definitions.end())
- return &i->second;
- else if (outer != 0)
- return outer->find(name);
- return 0;
- }
-
- environment* parent() const { return outer; }
-
- private:
-
- environment* outer;
- std::map<std::string, compiled_function> definitions;
- };
-
-///////////////////////////////////////////////////////////////////////////////
-// The compiler
-///////////////////////////////////////////////////////////////////////////////
- function compile(
- utree const& ast, environment& env, actor_list& fragments);
-
- struct external_function : composite<external_function>
- {
- // we must hold f by reference because functions can be recursive
- boost::reference_wrapper<function const> f;
-
- external_function(function const& f)
- : f(f) {}
-
- using base_type::operator();
- function operator()(actor_list const& elements) const
- {
- return function(lambda_function(f, elements));
- }
- };
-
- struct compiler
- {
- typedef function result_type;
- environment& env;
- actor_list& fragments;
-
- compiler(environment& env, actor_list& fragments)
- : env(env), fragments(fragments)
- {
- }
-
- function operator()(nil) const
- {
- return scheme::val(utree());
- }
-
- template <typename T>
- function operator()(T const& val) const
- {
- return scheme::val(utree(val));
- }
-
- function operator()(utf8_symbol_range const& str) const
- {
- std::string name(str.begin(), str.end());
- if (compiled_function* mf = env.find(name))
- {
- actor_list flist;
- return (*mf)(flist);
- }
- // $$$ throw? $$$
- BOOST_ASSERT(false);
- return function();
- }
-
- function make_lambda(
- std::vector<std::string> const& args,
- utree const& body) const
- {
- environment local_env(&this->env);
- for (std::size_t i = 0; i < args.size(); ++i)
- local_env.define(args[i], boost::bind(arg, i));
- return compile(body, local_env, fragments);
- }
-
- function define_function(
- std::string const& name,
- std::vector<std::string> const& args,
- utree const& body) const
- {
- fragments.push_back(function());
- function& f = fragments.back();
- env.define(name, external_function(f));
- f = make_lambda(args, body);
- return f;
- }
-
- template <typename Iterator>
- function operator()(boost::iterator_range<Iterator> const& range) const
- {
- std::string name(get_symbol(*range.begin()));
-
- if (name == "define")
- {
- std::string fname;
- std::vector<std::string> args;
-
- Iterator i = range.begin(); ++i;
- if (i->which() == utree_type::list_type)
- {
- // (define (f x) ...body...)
- utree const& decl = *i++;
- Iterator di = decl.begin();
- fname = get_symbol(*di++);
- while (di != decl.end())
- args.push_back(get_symbol(*di++));
- }
- else
- {
- // (define f ...body...)
- fname = get_symbol(*i++);
- }
-
- return define_function(fname, args, *i);
- }
-
- if (name == "lambda")
- {
- // (lambda (x) ...body...)
- Iterator i = range.begin(); ++i;
- utree const& arg_names = *i++;
- Iterator ai = arg_names.begin();
- std::vector<std::string> args;
- while (ai != arg_names.end())
- args.push_back(get_symbol(*ai++));
- return make_lambda(args, *i);
- }
-
- if (compiled_function* mf = env.find(name))
- {
- actor_list flist;
- Iterator i = range.begin(); ++i;
- for (; i != range.end(); ++i)
- flist.push_back(compile(*i, env, fragments));
- return (*mf)(flist);
- }
-
- BOOST_ASSERT(false);
- return function(); // $$$ implement me $$$
- }
-
- static std::string get_symbol(utree const& s)
- {
- utf8_symbol_range symbol = s.as<utf8_symbol_range>();
- return std::string(symbol.begin(), symbol.end());
- }
- };
-
- inline function compile(
- utree const& ast, environment& env, actor_list& fragments)
- {
- return utree::visit(ast, compiler(env, fragments));
- }
-
- void compile_all(
- utree const& ast,
- environment& env,
- actor_list& results,
- actor_list& fragments)
- {
- BOOST_FOREACH(utree const& program, ast)
- {
- scheme::function f = compile(program, env, fragments);
- results.push_back(f);
- }
- }
-
- void build_basic_environment(environment& env)
- {
- env.define("if", if_);
- env.define("<", less_than);
- env.define("<=", less_than_equal);
- env.define("+", plus);
- env.define("-", minus);
- env.define("*", times);
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // interpreter
- ///////////////////////////////////////////////////////////////////////////
- struct interpreter : actor<interpreter>
- {
- template <typename Source>
- interpreter(Source& in, environment* outer = 0)
- {
- if (outer == 0)
- build_basic_environment(env);
-
- if (input::parse_sexpr_list(in, program))
- {
- compile_all(program, env, flist, fragments);
- }
- else
- {
- // $$$ Use exceptions $$$
- BOOST_ASSERT(false);
- }
- }
-
- utree eval(args_type args) const
- {
- return flist.back()(args);
- }
-
- environment env;
- utree program;
- actor_list fragments;
- actor_list flist;
- };
-}
-
-#endif

Deleted: trunk/libs/spirit/example/scheme/scheme_interpreter.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme_interpreter.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
+++ (empty file)
@@ -1,406 +0,0 @@
-/*=============================================================================
- 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)
-=============================================================================*/
-#if !defined(BOOST_SPIRIT_SCHEME_INTERPRETER)
-#define BOOST_SPIRIT_SCHEME_INTERPRETER
-
-#include <list>
-#include <boost/function.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/scoped_array.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include "utree.hpp"
-
-#define SCHEME_COMPOSITE_LIMIT 10
-
-namespace scheme
-{
-///////////////////////////////////////////////////////////////////////////////
-// The runtime interpreter
-///////////////////////////////////////////////////////////////////////////////
-
- ///////////////////////////////////////////////////////////////////////////
- // typedefs
- ///////////////////////////////////////////////////////////////////////////
- struct function;
-
- typedef std::list<function> actor_list;
- typedef boost::iterator_range<utree const*> args_type;
- typedef boost::function<utree(args_type args)> stored_function;
-
- ///////////////////////////////////////////////////////////////////////////
- // actor
- ///////////////////////////////////////////////////////////////////////////
- template <typename Derived>
- struct actor
- {
- typedef utree result_type;
- typedef actor<Derived> base_type;
-
- utree operator()(args_type args) const
- {
- return derived().eval(args);
- }
-
- utree operator()() const
- {
- return derived().eval(args_type());
- }
-
- template <typename A0>
- utree operator()(A0 const& _0) const
- {
- boost::array<utree, 1> elements;
- elements[0] = _0;
- return derived().eval(get_range(elements));
- }
-
- template <typename A0, typename A1>
- utree operator()(A0 const& _0, A1 const& _1) const
- {
- boost::array<utree, 2> elements;
- elements[0] = _0;
- elements[1] = _1;
- return derived().eval(get_range(elements));
- }
-
- // More operators
- #include "detail/scheme_function_call.hpp"
-
- template <std::size_t n>
- static args_type
- get_range(boost::array<utree, n> const& array)
- {
- return args_type(array.begin(), array.end());
- }
-
- Derived const& derived() const
- {
- return *static_cast<Derived const*>(this);
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // function
- ///////////////////////////////////////////////////////////////////////////
- struct function : actor<function>
- {
- stored_function f;
- function()
- : f() {}
-
- function(stored_function const& f)
- : f(f)
- {
- BOOST_ASSERT(!f.empty());
- }
-
- bool empty() const
- {
- return f.empty();
- }
-
- utree eval(args_type args) const
- {
- return f(args);
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // values
- ///////////////////////////////////////////////////////////////////////////
- struct value_function : actor<value_function>
- {
- utree val;
- value_function(utree const& val) : val(val) {}
-
- utree eval(args_type /*args*/) const
- {
- return utree(boost::ref(val));
- }
- };
-
- struct value
- {
- typedef function result_type;
- function operator()(utree const& val) const
- {
- return function(value_function(val));
- }
- };
-
- value const val = {};
-
- ///////////////////////////////////////////////////////////////////////////
- // arguments
- ///////////////////////////////////////////////////////////////////////////
- struct argument_function : actor<argument_function>
- {
- std::size_t n;
- argument_function(std::size_t n) : n(n) {}
-
- utree eval(args_type args) const
- {
- return utree(boost::ref(args[n]));
- }
- };
-
- struct argument
- {
- typedef function result_type;
- function operator()(std::size_t n) const
- {
- return function(argument_function(n));
- }
- };
-
- argument const arg = {};
- function const _1 = arg(0);
- function const _2 = arg(1);
- function const _3 = arg(2);
- function const _4 = arg(3);
- function const _5 = arg(4);
- function const _6 = arg(5);
- function const _7 = arg(6);
- function const _8 = arg(7);
- function const _9 = arg(8);
- function const _10 = arg(10);
-
- ///////////////////////////////////////////////////////////////////////////
- // composite
- ///////////////////////////////////////////////////////////////////////////
- template <typename Derived>
- struct composite
- {
- typedef function result_type;
- typedef composite<Derived> base_type;
-
- function operator()(actor_list const& elements) const
- {
- return derived().compose(elements);
- }
-
- template <typename A0>
- function operator()(A0 const& _0) const
- {
- actor_list elements;
- elements.push_back(as_function(_0));
- return derived().compose(elements);
- }
-
- template <typename A0, typename A1>
- function operator()(A0 const& _0, A1 const& _1) const
- {
- actor_list elements;
- elements.push_back(as_function(_0));
- elements.push_back(as_function(_1));
- return derived().compose(elements);
- }
-
- // More operators
- #include "detail/scheme_composite_call.hpp"
-
- Derived const& derived() const
- {
- return *static_cast<Derived const*>(this);
- }
-
- template <typename T>
- static function as_function(T const& val)
- {
- return scheme::val(utree(val));
- }
-
- static function const& as_function(function const& f)
- {
- return f;
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // unary_function
- ///////////////////////////////////////////////////////////////////////////
- template <typename Derived>
- struct unary_function : actor<unary_function<Derived> >
- {
- function a;
- typedef unary_function<Derived> base_type;
-
- unary_function(function const& a)
- : a(a)
- {
- BOOST_ASSERT(!a.empty());
- }
-
- utree eval(args_type args) const
- {
- return derived().eval(a(args));
- }
-
- Derived const& derived() const
- {
- return *static_cast<Derived const*>(this);
- }
- };
-
- template <typename Function>
- struct unary_composite : composite<unary_composite<Function> >
- {
- function compose(actor_list const& elements) const
- {
- return function(Function(elements.front()));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // binary_function
- ///////////////////////////////////////////////////////////////////////////
- template <typename Derived>
- struct binary_function : actor<binary_function<Derived> >
- {
- function a;
- function b;
- typedef binary_function<Derived> base_type;
-
- binary_function(function const& a, function const& b)
- : a(a), b(b)
- {
- BOOST_ASSERT(!a.empty());
- BOOST_ASSERT(!b.empty());
- }
-
- utree eval(args_type args) const
- {
- return derived().eval(a(args), b(args));
- }
-
- Derived const& derived() const
- {
- return *static_cast<Derived const*>(this);
- }
- };
-
- template <typename Function>
- struct binary_composite : composite<binary_composite<Function> >
- {
- function compose(actor_list const& elements) const
- {
- actor_list::const_iterator i = elements.begin();
- function a = *i++;
- function b = *i;
- return function(Function(a, b));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // nary_function
- ///////////////////////////////////////////////////////////////////////////
- template <typename Derived>
- struct nary_function : actor<nary_function<Derived> >
- {
- actor_list elements;
- typedef nary_function<Derived> base_type;
-
- nary_function(actor_list const& elements)
- : elements(elements)
- {
- BOOST_FOREACH(function const& element, elements)
- {
- BOOST_ASSERT(!element.empty());
- }
- }
-
- utree eval(args_type 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(function const& element, rest)
- {
- if (!derived().eval(result, element(args)))
- break; // allow short-circuit evaluation
- }
- return result;
- }
-
- Derived const& derived() const
- {
- return *static_cast<Derived const*>(this);
- }
- };
-
- template <typename Function>
- struct nary_composite : composite<nary_composite<Function> >
- {
- function compose(actor_list const& elements) const
- {
- return function(Function(elements));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // lambda
- ///////////////////////////////////////////////////////////////////////////
- struct lambda_function : actor<lambda_function>
- {
- actor_list elements;
- // we must hold f by reference because functions can be recursive
- boost::reference_wrapper<function const> f;
-
- lambda_function(function const& f, actor_list const& elements)
- : elements(elements), f(f) {}
-
- typedef utree result_type;
- utree eval(args_type args) const
- {
- if (!elements.empty())
- {
- boost::scoped_array<utree>
- fargs(new utree[elements.size()]);
- std::size_t i = 0;
- BOOST_FOREACH(function const& element, elements)
- {
- fargs[i++] = element(args);
- }
- utree const* fi = fargs.get();
- return f.get()(args_type(fi, fi+elements.size()));
- }
- else
- {
- return f.get()();
- }
- }
- };
-
- struct lambda : composite<lambda>
- {
- function f;
-
- lambda() : f() {}
- lambda(function const& f) : f(f) {}
-
- function compose(actor_list const& elements) const
- {
- return function(lambda_function(f, elements));
- }
-
- lambda& operator=(lambda const& other)
- {
- f = other.f;
- return *this;
- }
-
- lambda& operator=(function const& f_)
- {
- f = f_;
- return *this;
- }
- };
-}
-
-#endif

Deleted: trunk/libs/spirit/example/scheme/scheme_intrinsics.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme_intrinsics.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
+++ (empty file)
@@ -1,154 +0,0 @@
-/*=============================================================================
- 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)
-=============================================================================*/
-#if !defined(BOOST_SPIRIT_SCHEME_INTRINSICS)
-#define BOOST_SPIRIT_SCHEME_INTRINSICS
-
-#include "scheme_interpreter.hpp"
-#include "utree_operators.hpp"
-
-namespace scheme
-{
- ///////////////////////////////////////////////////////////////////////////
- // if
- ///////////////////////////////////////////////////////////////////////////
- struct if_function : actor<if_function>
- {
- function cond;
- function then;
- function else_;
- if_function(
- function const& cond, function const& then, function const& else_)
- : cond(cond), then(then), else_(else_)
- {
- BOOST_ASSERT(!cond.empty());
- BOOST_ASSERT(!then.empty());
- BOOST_ASSERT(!else_.empty());
- }
-
- typedef utree result_type;
- utree eval(args_type args) const
- {
- return cond(args).as<bool>() ? then(args) : else_(args);
- }
- };
-
- struct if_composite : composite<if_composite>
- {
- function compose(actor_list const& elements) const
- {
- actor_list::const_iterator i = elements.begin();
- function if_ = *i++;
- function then = *i++;
- function else_ = *i;
- return function(if_function(if_, then, else_));
- }
- };
-
- if_composite const if_ = if_composite();
-
- ///////////////////////////////////////////////////////////////////////////
- // less_than
- ///////////////////////////////////////////////////////////////////////////
- struct less_than_function
- : binary_function<less_than_function>
- {
- less_than_function(function const& a, function const& b)
- : base_type(a, b) {}
-
- typedef utree result_type;
- utree eval(utree const& a, utree const& b) const
- {
- return a < b;
- }
- };
-
- struct less_than_composite
- : binary_composite<less_than_function> {};
-
- less_than_composite const less_than
- = less_than_composite();
- less_than_composite const lt = less_than; // synonym
-
- ///////////////////////////////////////////////////////////////////////////
- // less_than_equal
- ///////////////////////////////////////////////////////////////////////////
- struct less_than_equal_function
- : binary_function<less_than_equal_function>
- {
- less_than_equal_function(function const& a, function const& b)
- : base_type(a, b) {}
-
- typedef utree result_type;
- utree eval(utree const& a, utree const& b) const
- {
- return a <= b;
- }
- };
-
- struct less_than_equal_composite
- : binary_composite<less_than_equal_function> {};
-
- less_than_equal_composite const less_than_equal
- = less_than_equal_composite();
- less_than_equal_composite const lte = less_than_equal; // synonym
-
- ///////////////////////////////////////////////////////////////////////////
- // plus
- ///////////////////////////////////////////////////////////////////////////
- struct plus_function : nary_function<plus_function>
- {
- plus_function(actor_list const& elements)
- : base_type(elements) {}
-
- bool eval(utree& result, utree const& element) const
- {
- result = result + element;
- return true;
- }
- };
-
- struct plus_composite : nary_composite<plus_function> {};
- plus_composite const plus = plus_composite();
-
- ///////////////////////////////////////////////////////////////////////////
- // minus
- ///////////////////////////////////////////////////////////////////////////
- struct minus_function : nary_function<minus_function>
- {
- minus_function(actor_list const& elements)
- : base_type(elements) {}
-
- bool eval(utree& result, utree const& element) const
- {
- result = result - element;
- return true;
- }
- };
-
- struct minus_composite : nary_composite<minus_function> {};
- minus_composite const minus = minus_composite();
-
- ///////////////////////////////////////////////////////////////////////////
- // times
- ///////////////////////////////////////////////////////////////////////////
- struct times_function : nary_function<times_function>
- {
- times_function(actor_list const& elements)
- : base_type(elements) {}
-
- bool eval(utree& result, utree const& element) const
- {
- result = result * element;
- return true;
- }
- };
-
- struct times_composite : nary_composite<times_function> {};
- times_composite const times = times_composite();
-}
-
-#endif

Modified: trunk/libs/spirit/example/scheme/test/Jamfile
==============================================================================
--- trunk/libs/spirit/example/scheme/test/Jamfile (original)
+++ trunk/libs/spirit/example/scheme/test/Jamfile 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -5,7 +5,9 @@
 # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 #==============================================================================
 project spirit-scheme-tests
- : requirements <toolset>gcc:<c++-template-depth>300
+ : requirements
+ <toolset>gcc:<c++-template-depth>300
+ <include>../
     :
     :
     ;
@@ -14,14 +16,25 @@
 import testing ;
 
 {
- test-suite spirit_v2 :
+ test-suite utree :
 
- # run Qi tests
- [ run utree_test.cpp : : : : ]
+ # run utree tests
+ [ run utree/utree_test.cpp : : : : ]
 
     ;
 }
 
+exe sexpr_input_test : sexpr/sexpr_input_test.cpp ;
+exe sexpr_output_test : sexpr/sexpr_output_test.cpp ;
+
+exe generate_sexpr_to_ostream : parse_qiexpr/generate_sexpr_to_ostream.cpp ;
+exe parse_qi_test : parse_qiexpr/parse_qi_test.cpp ;
+exe parse_qiexpr : parse_qiexpr/parse_qiexpr.cpp ;
+
+exe scheme_test1 : scheme/scheme_test1.cpp ;
+exe scheme_test2 : scheme/scheme_test2.cpp ;
+exe scheme_test3 : scheme/scheme_test3.cpp ;
+
 
 
 

Modified: trunk/libs/spirit/example/scheme/test/parse_qiexpr/generate_sexpr_to_ostream.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/parse_qiexpr/generate_sexpr_to_ostream.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/parse_qiexpr/generate_sexpr_to_ostream.cpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -3,8 +3,8 @@
 // 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)
 
-#include "../../output/generate_sexpr.hpp"
-#include "../../output/generate_sexpr_impl.hpp"
+#include <output/generate_sexpr.hpp>
+#include <output/generate_sexpr_impl.hpp>
 
 #include <fstream>
 

Modified: trunk/libs/spirit/example/scheme/test/parse_qiexpr/parse_qi_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/parse_qiexpr/parse_qi_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/parse_qiexpr/parse_qi_test.cpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -11,9 +11,9 @@
 #include <fstream>
 #include <iterator>
 
-#include "../../utree.hpp"
-#include "../../qi/parse_qiexpr.hpp"
-#include "../../output/generate_sexpr.hpp"
+#include <utree.hpp>
+#include <qi/parse_qiexpr.hpp>
+#include <output/generate_sexpr.hpp>
 
 ///////////////////////////////////////////////////////////////////////////////
 // Main program

Modified: trunk/libs/spirit/example/scheme/test/parse_qiexpr/parse_qiexpr.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/parse_qiexpr/parse_qiexpr.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/parse_qiexpr/parse_qiexpr.cpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -5,8 +5,8 @@
 
 #include <fstream>
 
-#include "../../qi/parse_qiexpr.hpp"
-#include "../../qi/parse_qiexpr_impl.hpp"
+#include <qi/parse_qiexpr.hpp>
+#include <qi/parse_qiexpr_impl.hpp>
 
 // explicit template instantiation for the function parse_sexpr
 namespace scheme { namespace input

Modified: trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -6,9 +6,9 @@
 =============================================================================*/
 #include <boost/config/warning_disable.hpp>
 
-#include "../../input/parse_sexpr_impl.hpp"
-#include "../../scheme_compiler.hpp"
-#include "../../utree_io.hpp"
+#include <input/parse_sexpr_impl.hpp>
+#include <scheme/compiler.hpp>
+#include <utree/io.hpp>
 #include <iostream>
 #include <fstream>
 

Modified: trunk/libs/spirit/example/scheme/test/scheme/scheme_test2.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/scheme/scheme_test2.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/scheme/scheme_test2.cpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -6,8 +6,8 @@
 =============================================================================*/
 #include <boost/config/warning_disable.hpp>
 
-#include "../../scheme_compiler.hpp"
-#include "../../utree_io.hpp"
+#include <scheme/compiler.hpp>
+#include <utree/io.hpp>
 #include <iostream>
 #include <fstream>
 

Modified: trunk/libs/spirit/example/scheme/test/scheme/scheme_test3.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/scheme/scheme_test3.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/scheme/scheme_test3.cpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -6,10 +6,10 @@
 =============================================================================*/
 #include <boost/config/warning_disable.hpp>
 
-#include "../../input/sexpr.hpp"
-#include "../../input/parse_sexpr_impl.hpp"
-#include "../../scheme_compiler.hpp"
-#include "../../utree_io.hpp"
+#include <input/sexpr.hpp>
+#include <input/parse_sexpr_impl.hpp>
+#include <scheme/compiler.hpp>
+#include <utree/io.hpp>
 
 ///////////////////////////////////////////////////////////////////////////////
 // Main program

Modified: trunk/libs/spirit/example/scheme/test/sexpr/sexpr_input_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/sexpr/sexpr_input_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/sexpr/sexpr_input_test.cpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -6,9 +6,9 @@
 =============================================================================*/
 #include <boost/config/warning_disable.hpp>
 
-#include "../../input/sexpr.hpp"
-#include "../../input/parse_sexpr_impl.hpp"
-#include "../../utree_io.hpp"
+#include <input/sexpr.hpp>
+#include <input/parse_sexpr_impl.hpp>
+#include <utree/io.hpp>
 #include <iostream>
 #include <fstream>
 

Modified: trunk/libs/spirit/example/scheme/test/sexpr/sexpr_output_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/sexpr/sexpr_output_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/sexpr/sexpr_output_test.cpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -11,8 +11,8 @@
 #include <fstream>
 #include <iterator>
 
-#include "../../input/parse_sexpr_impl.hpp"
-#include "../../output/generate_sexpr_impl.hpp"
+#include <input/parse_sexpr_impl.hpp>
+#include <output/generate_sexpr_impl.hpp>
 
 namespace client
 {

Added: trunk/libs/spirit/example/scheme/test/utree/utree_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/test/utree/utree_test.cpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -0,0 +1,233 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+
+#include <boost/config/warning_disable.hpp>
+
+#include <utree/utree.hpp>
+#include <utree/operators.hpp>
+#include <utree/io.hpp>
+#include <iostream>
+#include <sstream>
+
+inline void check(scheme::utree const& val, std::string expected)
+{
+ std::stringstream s;
+ s << val;
+ BOOST_ASSERT(s.str() == expected);
+}
+
+int main()
+{
+ using scheme::utree;
+
+ {
+ // test the size
+ std::cout << "size of utree is: "
+ << sizeof(scheme::utree) << " bytes" << std::endl;
+ }
+
+ {
+ utree val;
+ check(val, "<nil>");
+ }
+
+ {
+ utree val(true);
+ check(val, "true");
+ }
+
+ {
+ utree val(123);
+ check(val, "123");
+ }
+
+ {
+ utree val(123.456);
+ check(val, "123.456");
+ }
+
+ {
+ utree val("Hello, World");
+ check(val, "\"Hello, World\"");
+ utree val2;
+ val2 = val;
+ check(val2, "\"Hello, World\"");
+ utree val3("Hello, World. Chuckie is back!!!");
+ val = val3;
+ check(val, "\"Hello, World. Chuckie is back!!!\"");
+
+ utree val4("Apple");
+ utree val5("Apple");
+ BOOST_ASSERT(val4 == val5);
+
+ utree val6("ApplePie");
+ BOOST_ASSERT(val4 < val6);
+ }
+
+ {
+ utree val;
+ val.push_back(123);
+ val.push_back("Chuckie");
+ BOOST_ASSERT(val.size() == 2);
+ utree val2;
+ val2.push_back(123.456);
+ val2.push_back("Mah Doggie");
+ val.push_back(val2);
+ BOOST_ASSERT(val.size() == 3);
+ check(val, "( 123 \"Chuckie\" ( 123.456 \"Mah Doggie\" ) )");
+ check(val.front(), "123");
+
+ utree val3;
+ val3.swap(val);
+ BOOST_ASSERT(val3.size() == 3);
+ check(val, "<nil>");
+ val3.swap(val);
+ check(val, "( 123 \"Chuckie\" ( 123.456 \"Mah Doggie\" ) )");
+ val.push_back("another string");
+ BOOST_ASSERT(val.size() == 4);
+ check(val, "( 123 \"Chuckie\" ( 123.456 \"Mah Doggie\" ) \"another string\" )");
+ val.pop_front();
+ check(val, "( \"Chuckie\" ( 123.456 \"Mah Doggie\" ) \"another string\" )");
+ utree::iterator i = val.begin();
+ ++++i;
+ val.insert(i, "Right in the middle");
+ BOOST_ASSERT(val.size() == 4);
+ check(val, "( \"Chuckie\" ( 123.456 \"Mah Doggie\" ) \"Right in the middle\" \"another string\" )");
+ val.pop_back();
+ check(val, "( \"Chuckie\" ( 123.456 \"Mah Doggie\" ) \"Right in the middle\" )");
+ BOOST_ASSERT(val.size() == 3);
+ utree::iterator it = val.end(); --it;
+ val.erase(it);
+ check(val, "( \"Chuckie\" ( 123.456 \"Mah Doggie\" ) )");
+ BOOST_ASSERT(val.size() == 2);
+
+ val.insert(val.begin(), val2.begin(), val2.end());
+ check(val, "( 123.456 \"Mah Doggie\" \"Chuckie\" ( 123.456 \"Mah Doggie\" ) )");
+ BOOST_ASSERT(val.size() == 4);
+ }
+
+ {
+ utree val;
+ val.insert(val.end(), 123);
+ val.insert(val.end(), "Mia");
+ val.insert(val.end(), "Chuckie");
+ val.insert(val.end(), "Poly");
+ val.insert(val.end(), "Mochi");
+ check(val, "( 123 \"Mia\" \"Chuckie\" \"Poly\" \"Mochi\" )");
+ }
+
+ {
+ utree a, b;
+ BOOST_ASSERT(a == b);
+ a = 123;
+ BOOST_ASSERT(a != b);
+ b = 123;
+ BOOST_ASSERT(a == b);
+ a = 100.00;
+ BOOST_ASSERT(a < b);
+
+ b = a = utree();
+ BOOST_ASSERT(a == b);
+ a.push_back(1);
+ a.push_back("two");
+ a.push_back(3.0);
+ b.push_back(1);
+ b.push_back("two");
+ b.push_back(3.0);
+ BOOST_ASSERT(a == b);
+ b.push_back(4);
+ BOOST_ASSERT(a != b);
+ BOOST_ASSERT(a < b);
+ }
+
+ {
+ utree a;
+ a.push_back(1);
+ a.push_back(2);
+ a.push_back(3);
+ a.push_back(4);
+ a.push_back(5);
+ a.push_back(6);
+ a.push_back(7);
+ a.push_back(8);
+ a.push_back(9);
+ a.push_back(10);
+ a.push_back(11);
+ a.push_back(12);
+
+ BOOST_ASSERT(a[0] == utree(1));
+ BOOST_ASSERT(a[1] == utree(2));
+ BOOST_ASSERT(a[2] == utree(3));
+ BOOST_ASSERT(a[3] == utree(4));
+ BOOST_ASSERT(a[4] == utree(5));
+ BOOST_ASSERT(a[5] == utree(6));
+ BOOST_ASSERT(a[6] == utree(7));
+ BOOST_ASSERT(a[7] == utree(8));
+ BOOST_ASSERT(a[8] == utree(9));
+ BOOST_ASSERT(a[9] == utree(10));
+ BOOST_ASSERT(a[10] == utree(11));
+ BOOST_ASSERT(a[11] == utree(12));
+ }
+
+ { // test references
+ utree val(123);
+ utree ref(boost::ref(val));
+ check(ref, "123");
+ BOOST_ASSERT(ref == utree(123));
+
+ val.clear();
+ val.push_back(1);
+ val.push_back(2);
+ val.push_back(3);
+ val.push_back(4);
+ check(ref, "( 1 2 3 4 )");
+ BOOST_ASSERT(ref[0] == utree(1));
+ BOOST_ASSERT(ref[1] == utree(2));
+ BOOST_ASSERT(ref[2] == utree(3));
+ BOOST_ASSERT(ref[3] == utree(4));
+ }
+
+ { // put it in an array
+
+ utree vals[] = {
+ utree(123),
+ utree("Hello, World"),
+ utree(123.456)
+ };
+
+ check(vals[0], "123");
+ check(vals[1], "\"Hello, World\"");
+ check(vals[2], "123.456");
+ }
+
+ { // operators
+
+ BOOST_ASSERT((utree(true) && utree(true)) == utree(true));
+ BOOST_ASSERT((utree(true) || utree(false)) == utree(true));
+ BOOST_ASSERT(!utree(true) == utree(false));
+
+ BOOST_ASSERT((utree(456) + utree(123)) == utree(456 + 123));
+ BOOST_ASSERT((utree(456) + utree(123.456)) == utree(456 + 123.456));
+ BOOST_ASSERT((utree(456) - utree(123)) == utree(456 - 123));
+ BOOST_ASSERT((utree(456) - utree(123.456)) == utree(456 - 123.456));
+ BOOST_ASSERT((utree(456) * utree(123)) == utree(456 * 123));
+ BOOST_ASSERT((utree(456) * utree(123.456)) == utree(456 * 123.456));
+ BOOST_ASSERT((utree(456) / utree(123)) == utree(456 / 123));
+ BOOST_ASSERT((utree(456) / utree(123.456)) == utree(456 / 123.456));
+ BOOST_ASSERT((utree(456) % utree(123)) == utree(456 % 123));
+ BOOST_ASSERT(-utree(456) == utree(-456));
+
+ BOOST_ASSERT((utree(456) & utree(123)) == utree(456 & 123));
+ BOOST_ASSERT((utree(456) | utree(123)) == utree(456 | 123));
+ BOOST_ASSERT((utree(456) ^ utree(123)) == utree(456 ^ 123));
+ BOOST_ASSERT((utree(456) << utree(3)) == utree(456 << 3));
+ BOOST_ASSERT((utree(456) >> utree(2)) == utree(456 >> 2));
+ BOOST_ASSERT(~utree(456) == utree(~456));
+ }
+
+ return 0;
+}

Deleted: trunk/libs/spirit/example/scheme/utree.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
+++ (empty file)
@@ -1,300 +0,0 @@
-/*=============================================================================
- 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)
-=============================================================================*/
-#if !defined(BOOST_SPIRIT_UTREE)
-#define BOOST_SPIRIT_UTREE
-
-#include <cstddef>
-#include <algorithm>
-#include <string>
-#include <ostream>
-
-#include <boost/assert.hpp>
-#include <boost/noncopyable.hpp>
-#include <boost/iterator/iterator_facade.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <boost/ref.hpp>
-#include "detail/utree_detail1.hpp"
-
-#if defined(BOOST_MSVC)
-# pragma warning(push)
-# pragma warning(disable: 4804)
-# pragma warning(disable: 4805)
-# pragma warning(disable: 4244)
-#endif
-
-namespace scheme
-{
- ///////////////////////////////////////////////////////////////////////////
- // Our utree can store these types. This enum tells us what type
- // of data is stored in utree's discriminated union.
- ///////////////////////////////////////////////////////////////////////////
- struct utree_type
- {
- enum info
- {
- nil_type,
- bool_type,
- int_type,
- double_type,
- string_type,
- symbol_type,
- binary_type,
- list_type,
- reference_type
- };
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // The nil type
- ///////////////////////////////////////////////////////////////////////////
- struct nil {};
-
- ///////////////////////////////////////////////////////////////////////////
- // A typed string with parametric Base storage. The storage can be any
- // range or (stl container) of chars.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Base, utree_type::info type_>
- struct basic_string : Base
- {
- static utree_type::info const type = type_;
-
- basic_string()
- : Base() {}
-
- basic_string(Base const& base)
- : Base(base) {}
-
- template <typename Iterator>
- basic_string(Iterator bits, std::size_t len)
- : Base(bits, bits + len) {}
-
- template <typename Iterator>
- basic_string(Iterator first, Iterator last)
- : Base(first, last) {}
-
- basic_string& operator=(basic_string const& other)
- {
- Base::operator=(other);
- return *this;
- }
-
- basic_string& operator=(Base const& other)
- {
- Base::operator=(other);
- return *this;
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // Binary string
- ///////////////////////////////////////////////////////////////////////////
- typedef basic_string<
- boost::iterator_range<char const*>,
- utree_type::binary_type>
- binary_range;
-
- typedef basic_string<
- std::string,
- utree_type::binary_type>
- binary_string;
-
- ///////////////////////////////////////////////////////////////////////////
- // Our UTF-8 string
- ///////////////////////////////////////////////////////////////////////////
- typedef basic_string<
- boost::iterator_range<char const*>,
- utree_type::string_type>
- utf8_string_range;
-
- typedef basic_string<
- std::string,
- utree_type::string_type>
- utf8_string;
-
- ///////////////////////////////////////////////////////////////////////////
- // Our UTF-8 symbol (for identifiers)
- ///////////////////////////////////////////////////////////////////////////
- typedef basic_string<
- boost::iterator_range<char const*>,
- utree_type::symbol_type>
- utf8_symbol_range;
-
- typedef basic_string<
- std::string,
- utree_type::symbol_type>
- utf8_symbol;
-
- ///////////////////////////////////////////////////////////////////////////
- // The main utree (Universal Tree) class
- // The utree is a hierarchical, dynamic type that can store:
- // - a nil
- // - a bool
- // - an integer
- // - a double
- // - a string
- // - a symbol (identifier)
- // - binary data
- // - a (doubly linked) list of utree
- // - a reference to a utree
- //
- // The utree has minimal memory footprint. The data structure size is
- // 16 bytes on a 32-bit platform. Being a container of itself, it can
- // represent tree structures.
- ///////////////////////////////////////////////////////////////////////////
- class utree
- {
- public:
-
- typedef utree value_type;
- typedef detail::list::node_iterator<utree> iterator;
- typedef detail::list::node_iterator<utree const> const_iterator;
- typedef utree& reference;
- typedef utree const& const_reference;
- typedef std::ptrdiff_t difference_type;
- typedef std::size_t size_type;
-
- typedef boost::iterator_range<iterator> range;
- typedef boost::iterator_range<const_iterator> const_range;
-
- utree();
- 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);
-
- template <typename Base, utree_type::info type_>
- utree(basic_string<Base, type_> const& bin);
-
- utree(utree const& other);
- ~utree();
-
- utree& operator=(utree const& other);
- utree& operator=(bool b);
- utree& operator=(unsigned int i);
- utree& operator=(int i);
- utree& operator=(double d);
- utree& operator=(char const* s);
- utree& operator=(std::string const& s);
- utree& operator=(boost::reference_wrapper<utree> ref);
-
- template <typename Base, utree_type::info type_>
- utree& operator=(basic_string<Base, type_> const& bin);
-
- template <typename F>
- typename F::result_type
- static visit(utree const& x, F f);
-
- template <typename F>
- typename F::result_type
- static visit(utree& x, F f);
-
- template <typename F>
- typename F::result_type
- static visit(utree const& x, utree const& y, F f);
-
- template <typename F>
- typename F::result_type
- static visit(utree& x, utree const& y, F f);
-
- template <typename F>
- typename F::result_type
- static visit(utree const& x, utree& y, F f);
-
- template <typename F>
- typename F::result_type
- static visit(utree& x, utree& y, F f);
-
- template <typename T>
- void push_back(T const& val);
-
- template <typename T>
- void push_front(T const& val);
-
- template <typename T>
- iterator insert(iterator pos, T const& x);
-
- template <typename T>
- void insert(iterator pos, std::size_t, T const& x);
-
- template <typename Iter>
- void insert(iterator pos, Iter first, Iter last);
-
- template <typename Iter>
- void assign(Iter first, Iter last);
-
- void clear();
- void pop_front();
- void pop_back();
- iterator erase(iterator pos);
- iterator erase(iterator first, iterator last);
-
- utree& front();
- utree& back();
- utree const& front() const;
- utree const& back() const;
-
- utree& operator[](std::size_t i);
- utree const& operator[](std::size_t i) const;
-
- void swap(utree& other);
-
- iterator begin();
- iterator end();
- const_iterator begin() const;
- const_iterator end() const;
-
- bool empty() const;
- std::size_t size() const;
-
- utree_type::info which() const;
-
- template <typename T>
- T as() const;
-
- utree& deref();
- utree const& deref() const;
-
- private:
-
- typedef utree_type type;
-
- template <typename UTreeX, typename UTreeY>
- friend struct detail::visit_impl;
- friend struct detail::index_impl;
-
- template <typename T>
- friend struct detail::get_impl;
-
- type::info get_type() const;
- void set_type(type::info t);
- void ensure_list_type();
- void free();
- void copy(utree const& other);
-
- union
- {
- detail::fast_string s;
- detail::list l;
- bool b;
- int i;
- double d;
- utree* p;
- };
- };
-}
-
-#if defined(BOOST_MSVC)
-# pragma warning(pop)
-#endif
-
-#include "detail/utree_detail2.hpp"
-
-#endif

Added: trunk/libs/spirit/example/scheme/utree/detail/utree_detail1.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/utree/detail/utree_detail1.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -0,0 +1,116 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_UTREE_DETAIL1)
+#define BOOST_SPIRIT_UTREE_DETAIL1
+
+#include <boost/type_traits/alignment_of.hpp>
+
+namespace scheme { namespace detail
+{
+ template <typename UTreeX, typename UTreeY>
+ struct visit_impl;
+ struct index_impl;
+ template <typename T>
+ struct get_impl;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Our POD double linked list. Straightforward implementation.
+ // This implementation is very primitive and is not meant to be
+ // used stand-alone. This is the internal data representation
+ // of lists in our utree.
+ ///////////////////////////////////////////////////////////////////////////
+ struct list // keep this a POD!
+ {
+ struct node;
+
+ template <typename Value>
+ class node_iterator;
+
+ void free();
+ void copy(list const& other);
+ void default_construct();
+
+ template <typename T>
+ void insert_before(T const& val, node* node);
+
+ template <typename T>
+ void insert_after(T const& val, node* node);
+
+ template <typename T>
+ void push_front(T const& val);
+
+ template <typename T>
+ void push_back(T const& val);
+
+ void pop_front();
+ void pop_back();
+ node* erase(node* pos);
+
+ node* first;
+ node* last;
+ std::size_t size;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Our POD fast string. This implementation is very primitive and is not
+ // meant to be used stand-alone. This is the internal data representation
+ // of strings in our utree. This is deliberately a POD to allow it to be
+ // placed in a union. This POD fast string specifically utilizes
+ // (sizeof(list) * alignment_of(list)) - (2 * sizeof(char)). In a 32 bit
+ // system, this is 14 bytes. The two extra bytes are used by utree to store
+ // management info.
+ //
+ // It is a const string (i.e. immutable). It stores the characters directly
+ // if possible and only uses the heap if the string does not fit. Null
+ // characters are allowed, making it suitable to encode raw binary. The
+ // string length is encoded in the first byte if the string is placed in-situ,
+ // else, the length plus a pointer to the string in the heap are stored.
+ ///////////////////////////////////////////////////////////////////////////
+ struct fast_string // Keep this a POD!
+ {
+ static std::size_t const
+ buff_size = (sizeof(list) + boost::alignment_of<list>::value)
+ / sizeof(char);
+
+ static std::size_t const
+ small_string_size = buff_size-sizeof(char);
+
+ static std::size_t const
+ max_string_len = small_string_size - 1;
+
+ struct heap_store
+ {
+ char* str;
+ std::size_t size;
+ };
+
+ union
+ {
+ char buff[buff_size];
+ heap_store heap;
+ };
+
+ int get_type() const;
+ void set_type(int t);
+ bool is_heap_allocated() const;
+
+ std::size_t size() const;
+ char const* str() const;
+
+ template <typename Iterator>
+ void construct(Iterator f, Iterator l);
+
+ void swap(fast_string& other);
+ void free();
+ void copy(fast_string const& other);
+
+ char& info();
+ char info() const;
+ };
+}}
+
+#endif

Added: trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -0,0 +1,983 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_UTREE_DETAIL2)
+#define BOOST_SPIRIT_UTREE_DETAIL2
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4800)
+#endif
+
+namespace scheme { namespace detail
+{
+ inline char& fast_string::info()
+ {
+ return buff[small_string_size];
+ }
+
+ inline char fast_string::info() const
+ {
+ return buff[small_string_size];
+ }
+
+ inline int fast_string::get_type() const
+ {
+ return info() >> 1;
+ }
+
+ inline void fast_string::set_type(int t)
+ {
+ info() = (t << 1) | (info() & 1);
+ }
+
+ inline bool fast_string::is_heap_allocated() const
+ {
+ return info() & 1;
+ }
+
+ inline std::size_t fast_string::size() const
+ {
+ if (is_heap_allocated())
+ return heap.size;
+ else
+ return max_string_len - buff[small_string_size - 1];
+ }
+
+ inline char const* fast_string::str() const
+ {
+ if (is_heap_allocated())
+ return heap.str;
+ else
+ return buff;
+ }
+
+ template <typename Iterator>
+ inline void fast_string::construct(Iterator f, Iterator l)
+ {
+ unsigned const size = l-f;
+ char* str;
+ if (size < small_string_size)
+ {
+ // if it fits, store it in-situ; small_string_size minus the length
+ // of the string is placed in buff[small_string_size - 1]
+ str = buff;
+ buff[small_string_size - 1] = max_string_len - size;
+ info() &= ~0x1;
+ }
+ else
+ {
+ // else, store it in the heap
+ str = new char[size + 1]; // add one for the null char
+ heap.str = str;
+ heap.size = size;
+ info() |= 0x1;
+ }
+ for (std::size_t i = 0; i != size; ++i)
+ {
+ *str++ = *f++;
+ }
+ *str = '\0'; // add the null char
+ }
+
+ inline void fast_string::swap(fast_string& other)
+ {
+ std::swap(*this, other);
+ }
+
+ inline void fast_string::free()
+ {
+ if (is_heap_allocated())
+ {
+ delete [] heap.str;
+ heap.str = 0;
+ }
+ }
+
+ inline void fast_string::copy(fast_string const& other)
+ {
+ construct(other.str(), other.str() + other.size());
+ }
+
+ struct list::node : boost::noncopyable
+ {
+ template <typename T>
+ node(T const& val, node* next, node* prev)
+ : val(val), next(next), prev(prev) {}
+
+ void unlink()
+ {
+ prev->next = next;
+ next->prev = prev;
+ }
+
+ utree val;
+ node* next;
+ node* prev;
+ };
+
+ template <typename Value>
+ class list::node_iterator
+ : public boost::iterator_facade<
+ node_iterator<Value>
+ , Value
+ , boost::bidirectional_traversal_tag
+ >
+ {
+ public:
+
+ node_iterator()
+ : node(0) {}
+
+ explicit node_iterator(list::node* node)
+ : node(node), prev(node->prev) {}
+
+ node_iterator(list::node* node, list::node* prev)
+ : node(node), prev(prev) {}
+
+ private:
+
+ friend class boost::iterator_core_access;
+ friend class scheme::utree;
+
+ void increment()
+ {
+ if (node != 0) // not at end
+ {
+ prev = node;
+ node = node->next;
+ }
+ }
+
+ void decrement()
+ {
+ if (prev != 0) // not at begin
+ {
+ node = prev;
+ prev = prev->prev;
+ }
+ }
+
+ bool equal(node_iterator const& other) const
+ {
+ return node == other.node;
+ }
+
+ utree& dereference() const
+ {
+ return node->val;
+ }
+
+ list::node* node;
+ list::node* prev;
+ };
+
+ inline void list::free()
+ {
+ node* p = first;
+ while (p != last)
+ {
+ node* next = p->next;
+ delete p;
+ p = next;
+ }
+ first = last = 0;
+ size = 0;
+ }
+
+ inline void list::copy(list const& other)
+ {
+ first = last = 0;
+ size = 0;
+ node* p = other.first;
+ while (p != 0)
+ {
+ push_back(p->val);
+ p = p->next;
+ }
+ }
+
+ inline void list::default_construct()
+ {
+ first = last = 0;
+ size = 0;
+ }
+
+ template <typename T>
+ inline void list::insert_before(T const& val, node* np)
+ {
+ BOOST_ASSERT(np != 0);
+ node* new_node = new node(val, np, np->prev);
+ if (np->prev)
+ np->prev->next = new_node;
+ else
+ first = new_node;
+ np->prev = new_node;
+ ++size;
+ }
+
+ template <typename T>
+ inline void list::insert_after(T const& val, node* np)
+ {
+ BOOST_ASSERT(np != 0);
+ node* new_node = new node(val, np->next, np);
+ if (np->next)
+ np->next->prev = new_node;
+ else
+ last = new_node;
+ np->next = new_node;
+ ++size;
+ }
+
+ template <typename T>
+ inline void list::push_front(T const& val)
+ {
+ detail::list::node* new_node;
+ if (first == 0)
+ {
+ new_node = new detail::list::node(val, 0, 0);
+ first = last = new_node;
+ ++size;
+ }
+ else
+ {
+ insert_before(val, first);
+ }
+ }
+
+ template <typename T>
+ inline void list::push_back(T const& val)
+ {
+ if (last == 0)
+ push_front(val);
+ else
+ insert_after(val, last);
+ }
+
+ inline void list::pop_front()
+ {
+ BOOST_ASSERT(size != 0);
+ node* np = first;
+ first = first->next;
+ first->prev = 0;
+ delete np;
+ --size;
+ }
+
+ inline void list::pop_back()
+ {
+ BOOST_ASSERT(size != 0);
+ node* np = last;
+ last = last->prev;
+ last->next = 0;
+ delete np;
+ --size;
+ }
+
+ inline list::node* list::erase(node* pos)
+ {
+ BOOST_ASSERT(pos != 0);
+ if (pos == first)
+ {
+ pop_front();
+ return first;
+ }
+ else if (pos == last)
+ {
+ pop_back();
+ return 0;
+ }
+ else
+ {
+ node* next(pos->next);
+ pos->unlink();
+ delete pos;
+ --size;
+ return next;
+ }
+ }
+
+ template <typename F, typename X>
+ struct bind_impl // simple binder for binary visitation (we don't want to bring in the big guns)
+ {
+ typedef typename F::result_type result_type;
+ X& x; // always by reference
+ F f;
+ bind_impl(F f, X& x) : x(x), f(f) {}
+
+ template <typename Y>
+ typename F::result_type operator()(Y& y) const
+ {
+ return f(x, y);
+ }
+
+ template <typename Y>
+ typename F::result_type operator()(Y const& y) const
+ {
+ return f(x, y);
+ }
+ };
+
+ template <typename F, typename X>
+ bind_impl<F, X const> bind(F f, X const& x)
+ {
+ return bind_impl<F, X const>(f, x);
+ }
+
+ template <typename F, typename X>
+ bind_impl<F, X> bind(F f, X& x)
+ {
+ return bind_impl<F, X>(f, x);
+ }
+
+ template <typename UTreeX, typename UTreeY = UTreeX>
+ struct visit_impl
+ {
+ template <typename F>
+ typename F::result_type
+ static apply(UTreeX& x, F f) // single dispatch
+ {
+ typedef typename
+ boost::mpl::if_<boost::is_const<UTreeX>,
+ typename UTreeX::const_iterator,
+ typename UTreeX::iterator>::type
+ iterator;
+
+ typedef boost::iterator_range<iterator> list_range;
+ typedef utree_type type;
+
+ switch (x.get_type())
+ {
+ default:
+ BOOST_ASSERT(false); // can't happen
+
+ case type::nil_type:
+ nil arg;
+ return f(arg);
+
+ case type::bool_type:
+ return f(x.b);
+
+ case type::int_type:
+ return f(x.i);
+
+ case type::double_type:
+ return f(x.d);
+
+ case type::list_type:
+ return f(list_range(iterator(x.l.first), iterator(0, x.l.last)));
+
+ case type::string_type:
+ return f(utf8_string_range(x.s.str(), x.s.size()));
+
+ case type::symbol_type:
+ return f(utf8_symbol_range(x.s.str(), x.s.size()));
+
+ case type::binary_type:
+ return f(binary_range(x.s.str(), x.s.size()));
+
+ case type::reference_type:
+ return apply(*x.p, f);
+ }
+ }
+
+ template <typename F>
+ typename F::result_type
+ static apply(UTreeX& x, UTreeY& y, F f) // double dispatch
+ {
+ typedef typename
+ boost::mpl::if_<boost::is_const<UTreeX>,
+ typename UTreeX::const_iterator,
+ typename UTreeX::iterator>::type
+ iterator;
+
+ typedef boost::iterator_range<iterator> list_range;
+ typedef utree_type type;
+
+ switch (x.get_type())
+ {
+ default:
+ BOOST_ASSERT(false); // can't happen
+
+ case type::nil_type:
+ nil x_;
+ return visit_impl::apply(y, detail::bind(f, x_));
+
+ case type::bool_type:
+ return visit_impl::apply(y, detail::bind(f, x.b));
+
+ case type::int_type:
+ return visit_impl::apply(y, detail::bind(f, x.i));
+
+ case type::double_type:
+ return visit_impl::apply(y, detail::bind(f, x.d));
+
+ case type::list_type:
+ return visit_impl::apply(
+ y, detail::bind<F, list_range>(f,
+ list_range(iterator(x.l.first), iterator(0, x.l.last))));
+
+ case type::string_type:
+ return visit_impl::apply(y, detail::bind(
+ f, utf8_string_range(x.s.str(), x.s.size())));
+
+ case type::symbol_type:
+ return visit_impl::apply(y, detail::bind(
+ f, utf8_symbol_range(x.s.str(), x.s.size())));
+
+ case type::binary_type:
+ return visit_impl::apply(y, detail::bind(
+ f, binary_range(x.s.str(), x.s.size())));
+
+ case type::reference_type:
+ return apply(*x.p, y, f);
+ }
+ }
+ };
+
+ struct index_impl
+ {
+ static utree& apply(list::node* node, std::size_t i)
+ {
+ for (; i > 0; --i)
+ node = node->next;
+ return node->val;
+ }
+
+ static utree const& apply(list::node const* node, std::size_t i)
+ {
+ for (; i > 0; --i)
+ node = node->next;
+ return node->val;
+ }
+ };
+}}
+
+namespace scheme
+{
+ inline utree::utree()
+ {
+ set_type(type::nil_type);
+ }
+
+ inline utree::utree(bool b) : b(b)
+ {
+ set_type(type::bool_type);
+ }
+
+ inline utree::utree(unsigned int i) : i(i)
+ {
+ set_type(type::int_type);
+ }
+
+ inline utree::utree(int i) : i(i)
+ {
+ set_type(type::int_type);
+ }
+
+ inline utree::utree(double d) : d(d)
+ {
+ set_type(type::double_type);
+ }
+
+ inline utree::utree(char const* str)
+ {
+ s.construct(str, str + strlen(str));
+ set_type(type::string_type);
+ }
+
+ inline utree::utree(char const* str, std::size_t len)
+ {
+ s.construct(str, str + len);
+ set_type(type::string_type);
+ }
+
+ inline utree::utree(std::string const& str)
+ {
+ s.construct(str.begin(), str.end());
+ set_type(type::string_type);
+ }
+
+ template <typename Base, utree_type::info type_>
+ inline utree::utree(basic_string<Base, type_> const& bin)
+ {
+ s.construct(bin.begin(), bin.end());
+ set_type(type_);
+ }
+
+ inline utree::utree(boost::reference_wrapper<utree> ref)
+ : p(ref.get_pointer())
+ {
+ set_type(type::reference_type);
+ }
+
+ inline utree::utree(utree const& other)
+ {
+ copy(other);
+ }
+
+ inline utree::~utree()
+ {
+ free();
+ }
+
+ inline utree& utree::operator=(utree const& other)
+ {
+ if (this != &other)
+ {
+ free();
+ copy(other);
+ }
+ return *this;
+ }
+
+ inline utree& utree::operator=(bool b_)
+ {
+ free();
+ b = b_;
+ set_type(type::bool_type);
+ return *this;
+ }
+
+ inline utree& utree::operator=(unsigned int i_)
+ {
+ free();
+ i = i_;
+ set_type(type::int_type);
+ return *this;
+ }
+
+ inline utree& utree::operator=(int i_)
+ {
+ free();
+ i = i_;
+ set_type(type::int_type);
+ return *this;
+ }
+
+ inline utree& utree::operator=(double d_)
+ {
+ free();
+ d = d_;
+ set_type(type::double_type);
+ return *this;
+ }
+
+ inline utree& utree::operator=(char const* s_)
+ {
+ free();
+ s.construct(s_, s_ + strlen(s_));
+ set_type(type::string_type);
+ return *this;
+ }
+
+ inline utree& utree::operator=(std::string const& s_)
+ {
+ free();
+ s.construct(s_.begin(), s_.end());
+ set_type(type::string_type);
+ return *this;
+ }
+
+ template <typename Base, utree_type::info type_>
+ inline utree& utree::operator=(basic_string<Base, type_> const& bin)
+ {
+ free();
+ s.construct(bin.begin(), bin.end());
+ set_type(type_);
+ return *this;
+ }
+
+ inline utree& utree::operator=(boost::reference_wrapper<utree> ref)
+ {
+ free();
+ p = ref.get_pointer();
+ set_type(type::reference_type);
+ return *this;
+ }
+
+ template <typename F>
+ typename F::result_type
+ inline utree::visit(utree const& x, F f)
+ {
+ return detail::visit_impl<utree const>::apply(x, f);
+ }
+
+ template <typename F>
+ typename F::result_type
+ inline utree::visit(utree& x, F f)
+ {
+ return detail::visit_impl<utree>::apply(x, f);
+ }
+
+ template <typename F>
+ typename F::result_type
+ inline utree::visit(utree const& x, utree const& y, F f)
+ {
+ return detail::visit_impl<utree const, utree const>::apply(x, y, f);
+ }
+
+ template <typename F>
+ typename F::result_type
+ inline utree::visit(utree const& x, utree& y, F f)
+ {
+ return detail::visit_impl<utree const, utree>::apply(x, y, f);
+ }
+
+ template <typename F>
+ typename F::result_type
+ inline utree::visit(utree& x, utree const& y, F f)
+ {
+ return detail::visit_impl<utree, utree const>::apply(x, y, f);
+ }
+
+ template <typename F>
+ typename F::result_type
+ inline utree::visit(utree& x, utree& y, F f)
+ {
+ return detail::visit_impl<utree, utree>::apply(x, y, f);
+ }
+
+ inline utree& utree::operator[](std::size_t i)
+ {
+ if (get_type() == type::reference_type)
+ return (*p)[i];
+ BOOST_ASSERT(get_type() == type::list_type && size() > i);
+ return detail::index_impl::apply(l.first, i);
+ }
+
+ inline utree const& utree::operator[](std::size_t i) const
+ {
+ if (get_type() == type::reference_type)
+ return (*(utree const*)p)[i];
+ BOOST_ASSERT(get_type() == type::list_type && size() > i);
+ return detail::index_impl::apply(l.first, i);
+ }
+
+ template <typename T>
+ inline void utree::push_front(T const& val)
+ {
+ if (get_type() == type::reference_type)
+ return p->push_front(val);
+ ensure_list_type();
+ l.push_front(val);
+ }
+
+ template <typename T>
+ inline void utree::push_back(T const& val)
+ {
+ if (get_type() == type::reference_type)
+ return p->push_back(val);
+ ensure_list_type();
+ l.push_back(val);
+ }
+
+ template <typename T>
+ inline utree::iterator utree::insert(iterator pos, T const& val)
+ {
+ if (get_type() == type::reference_type)
+ return p->insert(pos, val);
+ ensure_list_type();
+ if (pos == end())
+ {
+ push_back(val);
+ return begin();
+ }
+ else
+ {
+ l.insert_before(val, pos.node);
+ return utree::iterator(pos.node->prev);
+ }
+ }
+
+
+ template <typename T>
+ inline void utree::insert(iterator pos, std::size_t n, T const& val)
+ {
+ if (get_type() == type::reference_type)
+ return p->insert(pos, n, val);
+ for (std::size_t i = 0; i != n; ++i)
+ insert(pos, val);
+ }
+
+ template <typename Iter>
+ inline void utree::insert(iterator pos, Iter first, Iter last)
+ {
+ if (get_type() == type::reference_type)
+ return p->insert(pos, first, last);
+ ensure_list_type();
+ while (first != last)
+ insert(pos, *first++);
+ }
+
+ template <typename Iter>
+ inline void utree::assign(Iter first, Iter last)
+ {
+ if (get_type() == type::reference_type)
+ return p->assign(first, last);
+ ensure_list_type();
+ clear();
+ while (first != last)
+ push_back(*first++);
+ }
+
+ inline void utree::clear()
+ {
+ if (get_type() == type::reference_type)
+ return p->clear();
+ // clear will always make this a nil type
+ free();
+ set_type(type::nil_type);
+ }
+
+ inline void utree::pop_front()
+ {
+ if (get_type() == type::reference_type)
+ return p->pop_front();
+ BOOST_ASSERT(get_type() == type::list_type);
+ l.pop_front();
+ }
+
+ inline void utree::pop_back()
+ {
+ if (get_type() == type::reference_type)
+ return p->pop_back();
+ BOOST_ASSERT(get_type() == type::list_type);
+ l.pop_back();
+ }
+
+ inline utree::iterator utree::erase(iterator pos)
+ {
+ if (get_type() == type::reference_type)
+ return p->erase(pos);
+ BOOST_ASSERT(get_type() == type::list_type);
+ detail::list::node* np = l.erase(pos.node);
+ return iterator(np, np?np->prev:l.last);
+ }
+
+ inline utree::iterator utree::erase(iterator first, iterator last)
+ {
+ if (get_type() == type::reference_type)
+ return p->erase(first, last);
+ while (first != last)
+ erase(first++);
+ return last;
+ }
+
+ inline utree::iterator utree::begin()
+ {
+ if (get_type() == type::reference_type)
+ return p->begin();
+ ensure_list_type();
+ return iterator(l.first);
+ }
+
+ inline utree::iterator utree::end()
+ {
+ if (get_type() == type::reference_type)
+ return p->end();
+ ensure_list_type();
+ return iterator(0, l.last);
+ }
+
+ inline utree::const_iterator utree::begin() const
+ {
+ if (get_type() == type::reference_type)
+ return ((utree const*)p)->begin();
+ BOOST_ASSERT(get_type() == type::list_type);
+ return const_iterator(l.first);
+ }
+
+ inline utree::const_iterator utree::end() const
+ {
+ if (get_type() == type::reference_type)
+ return ((utree const*)p)->end();
+ BOOST_ASSERT(get_type() == type::list_type);
+ return const_iterator(0, l.last);
+ }
+
+ inline bool utree::empty() const
+ {
+ if (get_type() == type::reference_type)
+ return ((utree const*)p)->empty();
+ if (get_type() == type::list_type)
+ return l.size == 0;
+ BOOST_ASSERT(get_type() == type::nil_type);
+ return true;
+ }
+
+ inline std::size_t utree::size() const
+ {
+ if (get_type() == type::reference_type)
+ return ((utree const*)p)->size();
+ if (get_type() == type::list_type)
+ return l.size;
+ BOOST_ASSERT(get_type() == type::nil_type);
+ return 0;
+ }
+
+ inline utree_type::info utree::which() const
+ {
+ return get_type();
+ }
+
+ inline utree& utree::front()
+ {
+ if (get_type() == type::reference_type)
+ return p->front();
+ BOOST_ASSERT(get_type() == type::list_type && l.first != 0);
+ return l.first->val;
+ }
+
+ inline utree& utree::back()
+ {
+ if (get_type() == type::reference_type)
+ return p->back();
+ BOOST_ASSERT(get_type() == type::list_type && l.last != 0);
+ return l.last->val;
+ }
+
+ inline utree const& utree::front() const
+ {
+ if (get_type() == type::reference_type)
+ return ((utree const*)p)->front();
+ BOOST_ASSERT(get_type() == type::list_type && l.first != 0);
+ return l.first->val;
+ }
+
+ inline utree const& utree::back() const
+ {
+ if (get_type() == type::reference_type)
+ return ((utree const*)p)->back();
+ BOOST_ASSERT(get_type() == type::list_type && l.last != 0);
+ return l.last->val;
+ }
+
+ inline void utree::swap(utree& other)
+ {
+ s.swap(other.s);
+ }
+
+ inline utree::type::info utree::get_type() const
+ {
+ // the fast string holds the type info
+ return static_cast<utree::type::info>(s.get_type());
+ }
+
+ inline void utree::set_type(type::info t)
+ {
+ // the fast string holds the type info
+ s.set_type(t);
+ }
+
+ inline void utree::ensure_list_type()
+ {
+ if (get_type() == type::nil_type)
+ {
+ set_type(type::list_type);
+ l.default_construct();
+ }
+ else
+ {
+ BOOST_ASSERT(get_type() == type::list_type);
+ }
+ }
+
+ inline void utree::free()
+ {
+ switch (get_type())
+ {
+ case type::binary_type:
+ case type::symbol_type:
+ case type::string_type:
+ s.free();
+ break;
+ case type::list_type:
+ l.free();
+ break;
+ default:
+ break;
+ };
+ }
+
+ inline void utree::copy(utree const& other)
+ {
+ set_type(other.get_type());
+ switch (other.get_type())
+ {
+ case type::nil_type:
+ break;
+ case type::bool_type:
+ b = other.b;
+ break;
+ case type::int_type:
+ i = other.i;
+ break;
+ case type::double_type:
+ d = other.d;
+ break;
+ case type::reference_type:
+ p = other.p;
+ break;
+ case type::string_type:
+ case type::symbol_type:
+ case type::binary_type:
+ s.copy(other.s);
+ break;
+ case type::list_type:
+ l.copy(other.l);
+ break;
+ }
+ }
+
+ template <typename To>
+ struct utree_cast
+ {
+ typedef To result_type;
+
+ template <typename From>
+ To dispatch(From const& val, boost::mpl::true_) const
+ {
+ return To(val); // From is convertible to To
+ }
+
+ template <typename From>
+ To dispatch(From const& val, boost::mpl::false_) const
+ {
+ // From is NOT convertible to To !!!
+ BOOST_ASSERT(false);
+ return To();
+ }
+
+ template <typename From>
+ To operator()(From const& val) const
+ {
+ return dispatch(val, boost::is_convertible<From, To>());
+ }
+ };
+
+ template <typename T>
+ inline T utree::as() const
+ {
+ return utree::visit(*this, utree_cast<T>());
+ }
+
+ inline utree& utree::deref()
+ {
+ return (get_type() == type::reference_type) ? *p : *this;
+ }
+
+ inline utree const& utree::deref() const
+ {
+ return (get_type() == type::reference_type) ? *p : *this;
+ }
+}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif

Added: trunk/libs/spirit/example/scheme/utree/detail/utree_detail3.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/utree/detail/utree_detail3.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -0,0 +1,165 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_UTREE_DETAIL3)
+#define BOOST_SPIRIT_UTREE_DETAIL3
+
+#include <boost/variant/get.hpp> // boost::bad_get
+
+namespace scheme
+{
+ namespace detail
+ {
+ ///////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct get_utree_type;
+
+#define SCHEME_GET_UTREE_TYPE(t, v) \
+ template <> struct get_utree_type<t> { enum { value = v }; } \
+ /**/
+
+ SCHEME_GET_UTREE_TYPE(nil, utree_type::nil_type);
+ SCHEME_GET_UTREE_TYPE(bool, utree_type::bool_type);
+ SCHEME_GET_UTREE_TYPE(int, utree_type::int_type);
+ SCHEME_GET_UTREE_TYPE(double, utree_type::double_type);
+ SCHEME_GET_UTREE_TYPE(utf8_string_range, utree_type::string_type);
+ SCHEME_GET_UTREE_TYPE(utf8_string, utree_type::string_type);
+ SCHEME_GET_UTREE_TYPE(utf8_symbol_range, utree_type::symbol_type);
+ SCHEME_GET_UTREE_TYPE(utf8_symbol, utree_type::string_type);
+ SCHEME_GET_UTREE_TYPE(binary_range, utree_type::binary_type);
+ SCHEME_GET_UTREE_TYPE(boost::iterator_range<utree::iterator>,
+ utree_type::list_type);
+ SCHEME_GET_UTREE_TYPE(boost::iterator_range<utree::const_iterator>,
+ utree_type::list_type);
+
+#undef SCHEME_GET_UTREE_TYPE
+
+ ///////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct get_impl;
+
+ template <>
+ struct get_impl<nil>
+ {
+ typedef nil type;
+ static type call(utree const&) { return nil(); }
+ };
+
+ template <>
+ struct get_impl<bool>
+ {
+ typedef bool type;
+ static type call(utree const& x) { return x.b; }
+ };
+
+ template <>
+ struct get_impl<int>
+ {
+ typedef int type;
+ static type call(utree const& x) { return x.i; }
+ };
+
+ template <>
+ struct get_impl<double>
+ {
+ typedef double type;
+ static type call(utree const& x) { return x.d; }
+ };
+
+ template <>
+ struct get_impl<boost::iterator_range<utree::iterator> >
+ {
+ typedef boost::iterator_range<utree::iterator> type;
+ static type call(utree const& x)
+ {
+ return type(utree::iterator(x.l.first)
+ , utree::iterator(0, x.l.last));
+ }
+ };
+
+ template <>
+ struct get_impl<boost::iterator_range<utree::const_iterator> >
+ {
+ typedef boost::iterator_range<utree::const_iterator> type;
+ static type call(utree const& x)
+ {
+ return type(utree::const_iterator(x.l.first)
+ , utree::const_iterator(0, x.l.last));
+ }
+ };
+
+ template <>
+ struct get_impl<utf8_string_range>
+ {
+ typedef utf8_string_range type;
+ static type call(utree const& x)
+ {
+ return type(x.s.str(), x.s.size());
+ }
+ };
+
+ template <>
+ struct get_impl<utf8_string>
+ {
+ typedef utf8_string type;
+ static type call(utree const& x)
+ {
+ return type(x.s.str(), x.s.size());
+ }
+ };
+
+ template <>
+ struct get_impl<utf8_symbol_range>
+ {
+ typedef utf8_symbol_range type;
+ static type call(utree const& x)
+ {
+ return type(x.s.str(), x.s.size());
+ }
+ };
+
+ template <>
+ struct get_impl<utf8_symbol>
+ {
+ typedef utf8_symbol type;
+ static type call(utree const& x)
+ {
+ return type(x.s.str(), x.s.size());
+ }
+ };
+
+ template <>
+ struct get_impl<binary_range>
+ {
+ typedef binary_range type;
+ static type call(utree const& x)
+ {
+ return type(x.s.str(), x.s.size());
+ }
+ };
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost
+{
+ template <typename T>
+ typename scheme::detail::get_impl<T>::type
+ get(scheme::utree const& x)
+ {
+ if (x.which() !=
+ (scheme::utree_type::info)scheme::detail::get_utree_type<T>::value)
+ {
+ if (x.which() == scheme::utree_type::reference_type)
+ return get<T>(x.deref());
+
+ throw boost::bad_get();
+ }
+ return scheme::detail::get_impl<T>::call(x);
+ }
+}
+
+#endif

Added: trunk/libs/spirit/example/scheme/utree/io.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/utree/io.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -0,0 +1,31 @@
+// Copyright (c) 2001-2010 Hartmut Kaiser
+//
+// 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)
+
+#if !defined(BOOST_SPIRIT_UTREE_IO)
+#define BOOST_SPIRIT_UTREE_IO
+
+#include <utree/utree.hpp>
+#include <utree/operators.hpp>
+#include <input/parse_sexpr_impl.hpp>
+#include <output/generate_sexpr_impl.hpp>
+
+namespace scheme
+{
+ // Printing
+ inline std::ostream& operator<<(std::ostream& out, utree const& x)
+ {
+ output::generate_sexpr(out, x);
+ return out;
+ }
+
+ // Parsing
+ inline std::istream& operator>>(std::istream& in, utree& x)
+ {
+ input::parse_sexpr(in, x);
+ return in;
+ }
+}
+
+#endif

Added: trunk/libs/spirit/example/scheme/utree/operators.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/utree/operators.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -0,0 +1,530 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_UTREE_OPERATORS)
+#define BOOST_SPIRIT_UTREE_OPERATORS
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4804)
+# pragma warning(disable: 4805)
+#endif
+
+#include <utree/utree.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/type_traits/is_integral.hpp>
+
+namespace scheme
+{
+ // Relational operators
+ bool operator==(utree const& a, utree const& b);
+ bool operator<(utree const& a, utree const& b);
+ bool operator!=(utree const& a, utree const& b);
+ bool operator>(utree const& a, utree const& b);
+ bool operator<=(utree const& a, utree const& b);
+ bool operator>=(utree const& a, utree const& b);
+
+ // Input and output
+ std::ostream& operator<<(std::ostream& out, utree const& x);
+ std::istream& operator>>(std::istream& in, utree& x);
+
+ // Logical operators
+ utree operator&&(utree const& a, utree const& b);
+ utree operator||(utree const& a, utree const& b);
+ utree operator!(utree const& a);
+
+ // Arithmetic operators
+ utree operator+(utree const& a, utree const& b);
+ utree operator-(utree const& a, utree const& b);
+ utree operator*(utree const& a, utree const& b);
+ utree operator/(utree const& a, utree const& b);
+ utree operator%(utree const& a, utree const& b);
+ utree operator-(utree const& a);
+
+ // Bitwise operators
+ utree operator&(utree const& a, utree const& b);
+ utree operator|(utree const& a, utree const& b);
+ utree operator^(utree const& a, utree const& b);
+ utree operator<<(utree const& a, utree const& b);
+ utree operator>>(utree const& a, utree const& b);
+ utree operator~(utree const& a);
+
+ // Implementation
+ struct utree_is_equal
+ {
+ typedef bool result_type;
+
+ template <typename A, typename B>
+ bool dispatch(const A&, const B&, boost::mpl::false_) const
+ {
+ return false; // cannot compare different types by default
+ }
+
+ template <typename A, typename B>
+ bool dispatch(const A& a, const B& b, boost::mpl::true_) const
+ {
+ return a == b; // for arithmetic types
+ }
+
+ template <typename A, typename B>
+ bool operator()(const A& a, const B& b) const
+ {
+ return dispatch(a, b,
+ boost::mpl::and_<
+ boost::is_arithmetic<A>,
+ boost::is_arithmetic<B> >());
+ }
+
+ template <typename T>
+ bool operator()(const T& a, const T& b) const
+ {
+ // This code works for lists
+ return a == b;
+ }
+
+ template <typename Base, utree_type::info type_>
+ bool operator()(
+ basic_string<Base, type_> const& a,
+ basic_string<Base, type_> const& b) const
+ {
+ return static_cast<Base const&>(a) == static_cast<Base const&>(b);
+ }
+
+ bool operator()(nil, nil) const
+ {
+ return true;
+ }
+ };
+
+ struct utree_is_less_than
+ {
+ typedef bool result_type;
+
+ template <typename A, typename B>
+ bool dispatch(const A&, const B&, boost::mpl::false_) const
+ {
+ return false; // cannot compare different types by default
+ }
+
+ template <typename A, typename B>
+ bool dispatch(const A& a, const B& b, boost::mpl::true_) const
+ {
+ return a < b; // for arithmetic types
+ }
+
+ template <typename A, typename B>
+ bool operator()(const A& a, const B& b) const
+ {
+ return dispatch(a, b,
+ boost::mpl::and_<
+ boost::is_arithmetic<A>,
+ boost::is_arithmetic<B> >());
+ }
+
+ template <typename T>
+ bool operator()(const T& a, const T& b) const
+ {
+ // This code works for lists
+ return a < b;
+ }
+
+ template <typename Base, utree_type::info type_>
+ bool operator()(
+ basic_string<Base, type_> const& a,
+ basic_string<Base, type_> const& b) const
+ {
+ return static_cast<Base const&>(a) < static_cast<Base const&>(b);
+ }
+
+ bool operator()(nil, nil) const
+ {
+ BOOST_ASSERT(false);
+ return false; // no less than comparison for nil
+ }
+ };
+
+// struct utree_print
+// {
+// typedef void result_type;
+//
+// std::ostream& out;
+// utree_print(std::ostream& out) : out(out) {}
+//
+// void operator()(scheme::nil) const
+// {
+// out << "nil";
+// }
+//
+// template <typename T>
+// void operator()(T val) const
+// {
+// out << val;
+// }
+//
+// void operator()(bool b) const
+// {
+// out << (b ? "true" : "false");
+// }
+//
+// void operator()(binary_range const& b) const
+// {
+// out << "b";
+// out.width(2);
+// out.fill('0');
+//
+// typedef binary_range::const_iterator iterator;
+// for (iterator i = b.begin(); i != b.end(); ++i)
+// out << std::hex << int((unsigned char)*i);
+// out << std::dec;
+// }
+//
+// void operator()(utf8_string_range const& str) const
+// {
+// typedef utf8_string_range::const_iterator iterator;
+// iterator i = str.begin();
+// out << '"';
+// for (; i != str.end(); ++i)
+// out << *i;
+// out << '"';
+// }
+//
+// void operator()(utf8_symbol_range const& str) const
+// {
+// typedef utf8_symbol_range::const_iterator iterator;
+// iterator i = str.begin();
+// for (; i != str.end(); ++i)
+// out << *i;
+// }
+//
+// template <typename Iterator>
+// void operator()(boost::iterator_range<Iterator> const& range) const
+// {
+// typedef typename boost::iterator_range<Iterator>::const_iterator iterator;
+// (*this)('(');
+// for (iterator i = range.begin(); i != range.end(); ++i)
+// {
+// if (i != range.begin())
+// (*this)(' ');
+// scheme::utree::visit(*i, *this);
+// }
+// (*this)(')');
+// }
+// };
+
+ template <typename Base>
+ struct logical_function
+ {
+ typedef utree result_type;
+
+ // In scheme, anything except false is true
+
+ // binary
+ utree operator()(bool a, bool b) const
+ {
+ return Base::eval(a, b); // for boolean types
+ }
+
+ // binary
+ template <typename A>
+ utree operator()(A const& a, bool b) const
+ {
+ return Base::eval(true, b);
+ }
+
+ // binary
+ template <typename B>
+ utree operator()(bool a, B const& b) const
+ {
+ return Base::eval(a, true);
+ }
+
+ // binary
+ template <typename A, typename B>
+ utree operator()(A const& a, B const& b) const
+ {
+ return Base::eval(true, true);
+ }
+
+ // unary
+ utree operator()(bool a) const
+ {
+ return Base::eval(a);
+ }
+
+ // unary
+ template <typename A>
+ utree operator()(A const& a) const
+ {
+ return Base::eval(true);
+ }
+ };
+
+ template <typename Base>
+ struct arithmetic_function
+ {
+ typedef utree result_type;
+
+ template <typename A, typename B>
+ utree dispatch(A const&, B const&, boost::mpl::false_) const
+ {
+ // $$$ Throw exception here? $$$
+ return utree(); // cannot apply to non-arithmetic types
+ }
+
+ template <typename A, typename B>
+ utree dispatch(A const& a, B const& b, boost::mpl::true_) const
+ {
+ return Base::eval(a, b); // for arithmetic types
+ }
+
+ // binary
+ template <typename A, typename B>
+ utree operator()(A const& a, B const& b) const
+ {
+ return dispatch(a, b,
+ boost::mpl::and_<
+ boost::is_arithmetic<A>,
+ boost::is_arithmetic<B> >());
+ }
+
+ template <typename A>
+ utree dispatch(A const&, boost::mpl::false_) const
+ {
+ // $$$ Throw exception here? $$$
+ return utree(); // cannot apply to non-arithmetic types
+ }
+
+ template <typename A>
+ utree dispatch(A const& a, boost::mpl::true_) const
+ {
+ return Base::eval(a); // for arithmetic types
+ }
+
+ // unary
+ template <typename A>
+ utree operator()(A const& a) const
+ {
+ return dispatch(a, boost::is_arithmetic<A>());
+ }
+ };
+
+ template <typename Base>
+ struct integral_function
+ {
+ typedef utree result_type;
+
+ template <typename A, typename B>
+ utree dispatch(A const&, B const&, boost::mpl::false_) const
+ {
+ // $$$ Throw exception here? $$$
+ return utree(); // cannot apply to non-integral types
+ }
+
+ template <typename A, typename B>
+ utree dispatch(A const& a, B const& b, boost::mpl::true_) const
+ {
+ return Base::eval(a, b); // for integral types
+ }
+
+ // binary
+ template <typename A, typename B>
+ utree operator()(A const a, B const& b) const
+ {
+ return dispatch(a, b,
+ boost::mpl::and_<
+ boost::is_integral<A>,
+ boost::is_integral<B> >());
+ }
+
+ template <typename A>
+ utree dispatch(A const&, boost::mpl::false_) const
+ {
+ // $$$ Throw exception here? $$$
+ return utree(); // cannot apply to non-integral types
+ }
+
+ template <typename A>
+ utree dispatch(A const& a, boost::mpl::true_) const
+ {
+ return Base::eval(a); // for integral types
+ }
+
+ // unary
+ template <typename A>
+ utree operator()(A const& a) const
+ {
+ return dispatch(a, boost::is_integral<A>());
+ }
+ };
+
+#define SCHEME_CREATE_FUNCTION(name, expr, base) \
+ struct BOOST_PP_CAT(function_impl_, name) \
+ { \
+ template <typename A, typename B> \
+ static utree eval(A const& a, B const& b) \
+ { \
+ return utree(expr); \
+ } \
+ template <typename A> \
+ static utree eval(A const& a) \
+ { \
+ static int b; \
+ (void) b; \
+ return utree(expr); \
+ } \
+ }; \
+ base<BOOST_PP_CAT(function_impl_, name)> const \
+ BOOST_PP_CAT(base, BOOST_PP_CAT(_, name)) = {}; \
+ /***/
+
+#define SCHEME_CREATE_ARITHMETIC_FUNCTION(name, expr) \
+ SCHEME_CREATE_FUNCTION(name, expr, arithmetic_function) \
+ /***/
+
+#define SCHEME_CREATE_INTEGRAL_FUNCTION(name, expr) \
+ SCHEME_CREATE_FUNCTION(name, expr, integral_function) \
+ /***/
+
+#define SCHEME_CREATE_LOGICAL_FUNCTION(name, expr) \
+ SCHEME_CREATE_FUNCTION(name, expr, logical_function) \
+ /***/
+
+ inline bool operator==(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, utree_is_equal());
+ }
+
+ inline bool operator<(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, utree_is_less_than());
+ }
+
+ inline bool operator!=(utree const& a, utree const& b)
+ {
+ return !(a == b);
+ }
+
+ inline bool operator>(utree const& a, utree const& b)
+ {
+ return b < a;
+ }
+
+ inline bool operator<=(utree const& a, utree const& b)
+ {
+ return !(b < a);
+ }
+
+ inline bool operator>=(utree const& a, utree const& b)
+ {
+ return !(a < b);
+ }
+
+// inline std::ostream& operator<<(std::ostream& out, utree const& x)
+// {
+// utree::visit(x, utree_print(out));
+// return out;
+// }
+
+ SCHEME_CREATE_LOGICAL_FUNCTION(and_, a&&b);
+ SCHEME_CREATE_LOGICAL_FUNCTION(or_, a||b);
+ SCHEME_CREATE_LOGICAL_FUNCTION(not_, !a);
+
+ SCHEME_CREATE_ARITHMETIC_FUNCTION(plus, a+b);
+ SCHEME_CREATE_ARITHMETIC_FUNCTION(minus, a-b);
+ SCHEME_CREATE_ARITHMETIC_FUNCTION(times, a*b);
+ SCHEME_CREATE_ARITHMETIC_FUNCTION(divides, a/b);
+ SCHEME_CREATE_INTEGRAL_FUNCTION(modulus, a%b);
+ SCHEME_CREATE_ARITHMETIC_FUNCTION(negate, -a);
+
+ SCHEME_CREATE_INTEGRAL_FUNCTION(bitand_, a&b);
+ SCHEME_CREATE_INTEGRAL_FUNCTION(bitor_, a|b);
+ SCHEME_CREATE_INTEGRAL_FUNCTION(bitxor_, a^b);
+ SCHEME_CREATE_INTEGRAL_FUNCTION(shift_left, a<<b);
+ SCHEME_CREATE_INTEGRAL_FUNCTION(shift_right, a>>b);
+ SCHEME_CREATE_INTEGRAL_FUNCTION(invert, ~a);
+
+ inline utree operator&&(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, logical_function_and_);
+ }
+
+ inline utree operator||(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, logical_function_or_);
+ }
+
+ inline utree operator!(utree const& a)
+ {
+ return utree::visit(a, logical_function_not_);
+ }
+
+ inline utree operator+(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, arithmetic_function_plus);
+ }
+
+ inline utree operator-(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, arithmetic_function_minus);
+ }
+
+ inline utree operator*(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, arithmetic_function_times);
+ }
+
+ inline utree operator/(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, arithmetic_function_divides);
+ }
+
+ inline utree operator%(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, integral_function_modulus);
+ }
+
+ inline utree operator-(utree const& a)
+ {
+ return utree::visit(a, arithmetic_function_negate);
+ }
+
+ inline utree operator&(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, integral_function_bitand_);
+ }
+
+ inline utree operator|(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, integral_function_bitor_);
+ }
+
+ inline utree operator^(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, integral_function_bitxor_);
+ }
+
+ inline utree operator<<(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, integral_function_shift_left);
+ }
+
+ inline utree operator>>(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, integral_function_shift_right);
+ }
+
+ inline utree operator~(utree const& a)
+ {
+ return utree::visit(a, integral_function_invert);
+ }
+}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#endif

Added: trunk/libs/spirit/example/scheme/utree/utree.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/utree/utree.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
@@ -0,0 +1,300 @@
+/*=============================================================================
+ 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)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_UTREE)
+#define BOOST_SPIRIT_UTREE
+
+#include <cstddef>
+#include <algorithm>
+#include <string>
+#include <ostream>
+
+#include <boost/assert.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/ref.hpp>
+#include <utree/detail/utree_detail1.hpp>
+
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4804)
+# pragma warning(disable: 4805)
+# pragma warning(disable: 4244)
+#endif
+
+namespace scheme
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Our utree can store these types. This enum tells us what type
+ // of data is stored in utree's discriminated union.
+ ///////////////////////////////////////////////////////////////////////////
+ struct utree_type
+ {
+ enum info
+ {
+ nil_type,
+ bool_type,
+ int_type,
+ double_type,
+ string_type,
+ symbol_type,
+ binary_type,
+ list_type,
+ reference_type
+ };
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // The nil type
+ ///////////////////////////////////////////////////////////////////////////
+ struct nil {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // A typed string with parametric Base storage. The storage can be any
+ // range or (stl container) of chars.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Base, utree_type::info type_>
+ struct basic_string : Base
+ {
+ static utree_type::info const type = type_;
+
+ basic_string()
+ : Base() {}
+
+ basic_string(Base const& base)
+ : Base(base) {}
+
+ template <typename Iterator>
+ basic_string(Iterator bits, std::size_t len)
+ : Base(bits, bits + len) {}
+
+ template <typename Iterator>
+ basic_string(Iterator first, Iterator last)
+ : Base(first, last) {}
+
+ basic_string& operator=(basic_string const& other)
+ {
+ Base::operator=(other);
+ return *this;
+ }
+
+ basic_string& operator=(Base const& other)
+ {
+ Base::operator=(other);
+ return *this;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Binary string
+ ///////////////////////////////////////////////////////////////////////////
+ typedef basic_string<
+ boost::iterator_range<char const*>,
+ utree_type::binary_type>
+ binary_range;
+
+ typedef basic_string<
+ std::string,
+ utree_type::binary_type>
+ binary_string;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Our UTF-8 string
+ ///////////////////////////////////////////////////////////////////////////
+ typedef basic_string<
+ boost::iterator_range<char const*>,
+ utree_type::string_type>
+ utf8_string_range;
+
+ typedef basic_string<
+ std::string,
+ utree_type::string_type>
+ utf8_string;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Our UTF-8 symbol (for identifiers)
+ ///////////////////////////////////////////////////////////////////////////
+ typedef basic_string<
+ boost::iterator_range<char const*>,
+ utree_type::symbol_type>
+ utf8_symbol_range;
+
+ typedef basic_string<
+ std::string,
+ utree_type::symbol_type>
+ utf8_symbol;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // The main utree (Universal Tree) class
+ // The utree is a hierarchical, dynamic type that can store:
+ // - a nil
+ // - a bool
+ // - an integer
+ // - a double
+ // - a string
+ // - a symbol (identifier)
+ // - binary data
+ // - a (doubly linked) list of utree
+ // - a reference to a utree
+ //
+ // The utree has minimal memory footprint. The data structure size is
+ // 16 bytes on a 32-bit platform. Being a container of itself, it can
+ // represent tree structures.
+ ///////////////////////////////////////////////////////////////////////////
+ class utree
+ {
+ public:
+
+ typedef utree value_type;
+ typedef detail::list::node_iterator<utree> iterator;
+ typedef detail::list::node_iterator<utree const> const_iterator;
+ typedef utree& reference;
+ typedef utree const& const_reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::size_t size_type;
+
+ typedef boost::iterator_range<iterator> range;
+ typedef boost::iterator_range<const_iterator> const_range;
+
+ utree();
+ 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);
+
+ template <typename Base, utree_type::info type_>
+ utree(basic_string<Base, type_> const& bin);
+
+ utree(utree const& other);
+ ~utree();
+
+ utree& operator=(utree const& other);
+ utree& operator=(bool b);
+ utree& operator=(unsigned int i);
+ utree& operator=(int i);
+ utree& operator=(double d);
+ utree& operator=(char const* s);
+ utree& operator=(std::string const& s);
+ utree& operator=(boost::reference_wrapper<utree> ref);
+
+ template <typename Base, utree_type::info type_>
+ utree& operator=(basic_string<Base, type_> const& bin);
+
+ template <typename F>
+ typename F::result_type
+ static visit(utree const& x, F f);
+
+ template <typename F>
+ typename F::result_type
+ static visit(utree& x, F f);
+
+ template <typename F>
+ typename F::result_type
+ static visit(utree const& x, utree const& y, F f);
+
+ template <typename F>
+ typename F::result_type
+ static visit(utree& x, utree const& y, F f);
+
+ template <typename F>
+ typename F::result_type
+ static visit(utree const& x, utree& y, F f);
+
+ template <typename F>
+ typename F::result_type
+ static visit(utree& x, utree& y, F f);
+
+ template <typename T>
+ void push_back(T const& val);
+
+ template <typename T>
+ void push_front(T const& val);
+
+ template <typename T>
+ iterator insert(iterator pos, T const& x);
+
+ template <typename T>
+ void insert(iterator pos, std::size_t, T const& x);
+
+ template <typename Iter>
+ void insert(iterator pos, Iter first, Iter last);
+
+ template <typename Iter>
+ void assign(Iter first, Iter last);
+
+ void clear();
+ void pop_front();
+ void pop_back();
+ iterator erase(iterator pos);
+ iterator erase(iterator first, iterator last);
+
+ utree& front();
+ utree& back();
+ utree const& front() const;
+ utree const& back() const;
+
+ utree& operator[](std::size_t i);
+ utree const& operator[](std::size_t i) const;
+
+ void swap(utree& other);
+
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ bool empty() const;
+ std::size_t size() const;
+
+ utree_type::info which() const;
+
+ template <typename T>
+ T as() const;
+
+ utree& deref();
+ utree const& deref() const;
+
+ private:
+
+ typedef utree_type type;
+
+ template <typename UTreeX, typename UTreeY>
+ friend struct detail::visit_impl;
+ friend struct detail::index_impl;
+
+ template <typename T>
+ friend struct detail::get_impl;
+
+ type::info get_type() const;
+ void set_type(type::info t);
+ void ensure_list_type();
+ void free();
+ void copy(utree const& other);
+
+ union
+ {
+ detail::fast_string s;
+ detail::list l;
+ bool b;
+ int i;
+ double d;
+ utree* p;
+ };
+ };
+}
+
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
+#include <utree/detail/utree_detail2.hpp>
+
+#endif

Deleted: trunk/libs/spirit/example/scheme/utree_io.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree_io.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
+++ (empty file)
@@ -1,31 +0,0 @@
-// Copyright (c) 2001-2010 Hartmut Kaiser
-//
-// 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)
-
-#if !defined(BOOST_SPIRIT_UTREE_IO)
-#define BOOST_SPIRIT_UTREE_IO
-
-#include "utree.hpp"
-#include "utree_operators.hpp"
-#include "input/parse_sexpr_impl.hpp"
-#include "output/generate_sexpr_impl.hpp"
-
-namespace scheme
-{
- // Printing
- inline std::ostream& operator<<(std::ostream& out, utree const& x)
- {
- output::generate_sexpr(out, x);
- return out;
- }
-
- // Parsing
- inline std::istream& operator>>(std::istream& in, utree& x)
- {
- input::parse_sexpr(in, x);
- return in;
- }
-}
-
-#endif

Deleted: trunk/libs/spirit/example/scheme/utree_operators.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree_operators.hpp 2010-04-15 11:40:37 EDT (Thu, 15 Apr 2010)
+++ (empty file)
@@ -1,530 +0,0 @@
-/*=============================================================================
- 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)
-=============================================================================*/
-#if !defined(BOOST_SPIRIT_UTREE_OPERATORS)
-#define BOOST_SPIRIT_UTREE_OPERATORS
-
-#if defined(BOOST_MSVC)
-# pragma warning(push)
-# pragma warning(disable: 4804)
-# pragma warning(disable: 4805)
-#endif
-
-#include "utree.hpp"
-#include <boost/preprocessor/cat.hpp>
-#include <boost/type_traits/is_arithmetic.hpp>
-#include <boost/type_traits/is_integral.hpp>
-
-namespace scheme
-{
- // Relational operators
- bool operator==(utree const& a, utree const& b);
- bool operator<(utree const& a, utree const& b);
- bool operator!=(utree const& a, utree const& b);
- bool operator>(utree const& a, utree const& b);
- bool operator<=(utree const& a, utree const& b);
- bool operator>=(utree const& a, utree const& b);
-
- // Input and output
- std::ostream& operator<<(std::ostream& out, utree const& x);
- std::istream& operator>>(std::istream& in, utree& x);
-
- // Logical operators
- utree operator&&(utree const& a, utree const& b);
- utree operator||(utree const& a, utree const& b);
- utree operator!(utree const& a);
-
- // Arithmetic operators
- utree operator+(utree const& a, utree const& b);
- utree operator-(utree const& a, utree const& b);
- utree operator*(utree const& a, utree const& b);
- utree operator/(utree const& a, utree const& b);
- utree operator%(utree const& a, utree const& b);
- utree operator-(utree const& a);
-
- // Bitwise operators
- utree operator&(utree const& a, utree const& b);
- utree operator|(utree const& a, utree const& b);
- utree operator^(utree const& a, utree const& b);
- utree operator<<(utree const& a, utree const& b);
- utree operator>>(utree const& a, utree const& b);
- utree operator~(utree const& a);
-
- // Implementation
- struct utree_is_equal
- {
- typedef bool result_type;
-
- template <typename A, typename B>
- bool dispatch(const A&, const B&, boost::mpl::false_) const
- {
- return false; // cannot compare different types by default
- }
-
- template <typename A, typename B>
- bool dispatch(const A& a, const B& b, boost::mpl::true_) const
- {
- return a == b; // for arithmetic types
- }
-
- template <typename A, typename B>
- bool operator()(const A& a, const B& b) const
- {
- return dispatch(a, b,
- boost::mpl::and_<
- boost::is_arithmetic<A>,
- boost::is_arithmetic<B> >());
- }
-
- template <typename T>
- bool operator()(const T& a, const T& b) const
- {
- // This code works for lists
- return a == b;
- }
-
- template <typename Base, utree_type::info type_>
- bool operator()(
- basic_string<Base, type_> const& a,
- basic_string<Base, type_> const& b) const
- {
- return static_cast<Base const&>(a) == static_cast<Base const&>(b);
- }
-
- bool operator()(nil, nil) const
- {
- return true;
- }
- };
-
- struct utree_is_less_than
- {
- typedef bool result_type;
-
- template <typename A, typename B>
- bool dispatch(const A&, const B&, boost::mpl::false_) const
- {
- return false; // cannot compare different types by default
- }
-
- template <typename A, typename B>
- bool dispatch(const A& a, const B& b, boost::mpl::true_) const
- {
- return a < b; // for arithmetic types
- }
-
- template <typename A, typename B>
- bool operator()(const A& a, const B& b) const
- {
- return dispatch(a, b,
- boost::mpl::and_<
- boost::is_arithmetic<A>,
- boost::is_arithmetic<B> >());
- }
-
- template <typename T>
- bool operator()(const T& a, const T& b) const
- {
- // This code works for lists
- return a < b;
- }
-
- template <typename Base, utree_type::info type_>
- bool operator()(
- basic_string<Base, type_> const& a,
- basic_string<Base, type_> const& b) const
- {
- return static_cast<Base const&>(a) < static_cast<Base const&>(b);
- }
-
- bool operator()(nil, nil) const
- {
- BOOST_ASSERT(false);
- return false; // no less than comparison for nil
- }
- };
-
-// struct utree_print
-// {
-// typedef void result_type;
-//
-// std::ostream& out;
-// utree_print(std::ostream& out) : out(out) {}
-//
-// void operator()(scheme::nil) const
-// {
-// out << "nil";
-// }
-//
-// template <typename T>
-// void operator()(T val) const
-// {
-// out << val;
-// }
-//
-// void operator()(bool b) const
-// {
-// out << (b ? "true" : "false");
-// }
-//
-// void operator()(binary_range const& b) const
-// {
-// out << "b";
-// out.width(2);
-// out.fill('0');
-//
-// typedef binary_range::const_iterator iterator;
-// for (iterator i = b.begin(); i != b.end(); ++i)
-// out << std::hex << int((unsigned char)*i);
-// out << std::dec;
-// }
-//
-// void operator()(utf8_string_range const& str) const
-// {
-// typedef utf8_string_range::const_iterator iterator;
-// iterator i = str.begin();
-// out << '"';
-// for (; i != str.end(); ++i)
-// out << *i;
-// out << '"';
-// }
-//
-// void operator()(utf8_symbol_range const& str) const
-// {
-// typedef utf8_symbol_range::const_iterator iterator;
-// iterator i = str.begin();
-// for (; i != str.end(); ++i)
-// out << *i;
-// }
-//
-// template <typename Iterator>
-// void operator()(boost::iterator_range<Iterator> const& range) const
-// {
-// typedef typename boost::iterator_range<Iterator>::const_iterator iterator;
-// (*this)('(');
-// for (iterator i = range.begin(); i != range.end(); ++i)
-// {
-// if (i != range.begin())
-// (*this)(' ');
-// scheme::utree::visit(*i, *this);
-// }
-// (*this)(')');
-// }
-// };
-
- template <typename Base>
- struct logical_function
- {
- typedef utree result_type;
-
- // In scheme, anything except false is true
-
- // binary
- utree operator()(bool a, bool b) const
- {
- return Base::eval(a, b); // for boolean types
- }
-
- // binary
- template <typename A>
- utree operator()(A const& a, bool b) const
- {
- return Base::eval(true, b);
- }
-
- // binary
- template <typename B>
- utree operator()(bool a, B const& b) const
- {
- return Base::eval(a, true);
- }
-
- // binary
- template <typename A, typename B>
- utree operator()(A const& a, B const& b) const
- {
- return Base::eval(true, true);
- }
-
- // unary
- utree operator()(bool a) const
- {
- return Base::eval(a);
- }
-
- // unary
- template <typename A>
- utree operator()(A const& a) const
- {
- return Base::eval(true);
- }
- };
-
- template <typename Base>
- struct arithmetic_function
- {
- typedef utree result_type;
-
- template <typename A, typename B>
- utree dispatch(A const&, B const&, boost::mpl::false_) const
- {
- // $$$ Throw exception here? $$$
- return utree(); // cannot apply to non-arithmetic types
- }
-
- template <typename A, typename B>
- utree dispatch(A const& a, B const& b, boost::mpl::true_) const
- {
- return Base::eval(a, b); // for arithmetic types
- }
-
- // binary
- template <typename A, typename B>
- utree operator()(A const& a, B const& b) const
- {
- return dispatch(a, b,
- boost::mpl::and_<
- boost::is_arithmetic<A>,
- boost::is_arithmetic<B> >());
- }
-
- template <typename A>
- utree dispatch(A const&, boost::mpl::false_) const
- {
- // $$$ Throw exception here? $$$
- return utree(); // cannot apply to non-arithmetic types
- }
-
- template <typename A>
- utree dispatch(A const& a, boost::mpl::true_) const
- {
- return Base::eval(a); // for arithmetic types
- }
-
- // unary
- template <typename A>
- utree operator()(A const& a) const
- {
- return dispatch(a, boost::is_arithmetic<A>());
- }
- };
-
- template <typename Base>
- struct integral_function
- {
- typedef utree result_type;
-
- template <typename A, typename B>
- utree dispatch(A const&, B const&, boost::mpl::false_) const
- {
- // $$$ Throw exception here? $$$
- return utree(); // cannot apply to non-integral types
- }
-
- template <typename A, typename B>
- utree dispatch(A const& a, B const& b, boost::mpl::true_) const
- {
- return Base::eval(a, b); // for integral types
- }
-
- // binary
- template <typename A, typename B>
- utree operator()(A const a, B const& b) const
- {
- return dispatch(a, b,
- boost::mpl::and_<
- boost::is_integral<A>,
- boost::is_integral<B> >());
- }
-
- template <typename A>
- utree dispatch(A const&, boost::mpl::false_) const
- {
- // $$$ Throw exception here? $$$
- return utree(); // cannot apply to non-integral types
- }
-
- template <typename A>
- utree dispatch(A const& a, boost::mpl::true_) const
- {
- return Base::eval(a); // for integral types
- }
-
- // unary
- template <typename A>
- utree operator()(A const& a) const
- {
- return dispatch(a, boost::is_integral<A>());
- }
- };
-
-#define SCHEME_CREATE_FUNCTION(name, expr, base) \
- struct BOOST_PP_CAT(function_impl_, name) \
- { \
- template <typename A, typename B> \
- static utree eval(A const& a, B const& b) \
- { \
- return utree(expr); \
- } \
- template <typename A> \
- static utree eval(A const& a) \
- { \
- static int b; \
- (void) b; \
- return utree(expr); \
- } \
- }; \
- base<BOOST_PP_CAT(function_impl_, name)> const \
- BOOST_PP_CAT(base, BOOST_PP_CAT(_, name)) = {}; \
- /***/
-
-#define SCHEME_CREATE_ARITHMETIC_FUNCTION(name, expr) \
- SCHEME_CREATE_FUNCTION(name, expr, arithmetic_function) \
- /***/
-
-#define SCHEME_CREATE_INTEGRAL_FUNCTION(name, expr) \
- SCHEME_CREATE_FUNCTION(name, expr, integral_function) \
- /***/
-
-#define SCHEME_CREATE_LOGICAL_FUNCTION(name, expr) \
- SCHEME_CREATE_FUNCTION(name, expr, logical_function) \
- /***/
-
- inline bool operator==(utree const& a, utree const& b)
- {
- return utree::visit(a, b, utree_is_equal());
- }
-
- inline bool operator<(utree const& a, utree const& b)
- {
- return utree::visit(a, b, utree_is_less_than());
- }
-
- inline bool operator!=(utree const& a, utree const& b)
- {
- return !(a == b);
- }
-
- inline bool operator>(utree const& a, utree const& b)
- {
- return b < a;
- }
-
- inline bool operator<=(utree const& a, utree const& b)
- {
- return !(b < a);
- }
-
- inline bool operator>=(utree const& a, utree const& b)
- {
- return !(a < b);
- }
-
-// inline std::ostream& operator<<(std::ostream& out, utree const& x)
-// {
-// utree::visit(x, utree_print(out));
-// return out;
-// }
-
- SCHEME_CREATE_LOGICAL_FUNCTION(and_, a&&b);
- SCHEME_CREATE_LOGICAL_FUNCTION(or_, a||b);
- SCHEME_CREATE_LOGICAL_FUNCTION(not_, !a);
-
- SCHEME_CREATE_ARITHMETIC_FUNCTION(plus, a+b);
- SCHEME_CREATE_ARITHMETIC_FUNCTION(minus, a-b);
- SCHEME_CREATE_ARITHMETIC_FUNCTION(times, a*b);
- SCHEME_CREATE_ARITHMETIC_FUNCTION(divides, a/b);
- SCHEME_CREATE_INTEGRAL_FUNCTION(modulus, a%b);
- SCHEME_CREATE_ARITHMETIC_FUNCTION(negate, -a);
-
- SCHEME_CREATE_INTEGRAL_FUNCTION(bitand_, a&b);
- SCHEME_CREATE_INTEGRAL_FUNCTION(bitor_, a|b);
- SCHEME_CREATE_INTEGRAL_FUNCTION(bitxor_, a^b);
- SCHEME_CREATE_INTEGRAL_FUNCTION(shift_left, a<<b);
- SCHEME_CREATE_INTEGRAL_FUNCTION(shift_right, a>>b);
- SCHEME_CREATE_INTEGRAL_FUNCTION(invert, ~a);
-
- inline utree operator&&(utree const& a, utree const& b)
- {
- return utree::visit(a, b, logical_function_and_);
- }
-
- inline utree operator||(utree const& a, utree const& b)
- {
- return utree::visit(a, b, logical_function_or_);
- }
-
- inline utree operator!(utree const& a)
- {
- return utree::visit(a, logical_function_not_);
- }
-
- inline utree operator+(utree const& a, utree const& b)
- {
- return utree::visit(a, b, arithmetic_function_plus);
- }
-
- inline utree operator-(utree const& a, utree const& b)
- {
- return utree::visit(a, b, arithmetic_function_minus);
- }
-
- inline utree operator*(utree const& a, utree const& b)
- {
- return utree::visit(a, b, arithmetic_function_times);
- }
-
- inline utree operator/(utree const& a, utree const& b)
- {
- return utree::visit(a, b, arithmetic_function_divides);
- }
-
- inline utree operator%(utree const& a, utree const& b)
- {
- return utree::visit(a, b, integral_function_modulus);
- }
-
- inline utree operator-(utree const& a)
- {
- return utree::visit(a, arithmetic_function_negate);
- }
-
- inline utree operator&(utree const& a, utree const& b)
- {
- return utree::visit(a, b, integral_function_bitand_);
- }
-
- inline utree operator|(utree const& a, utree const& b)
- {
- return utree::visit(a, b, integral_function_bitor_);
- }
-
- inline utree operator^(utree const& a, utree const& b)
- {
- return utree::visit(a, b, integral_function_bitxor_);
- }
-
- inline utree operator<<(utree const& a, utree const& b)
- {
- return utree::visit(a, b, integral_function_shift_left);
- }
-
- inline utree operator>>(utree const& a, utree const& b)
- {
- return utree::visit(a, b, integral_function_shift_right);
- }
-
- inline utree operator~(utree const& a)
- {
- return utree::visit(a, integral_function_invert);
- }
-}
-
-#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