Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61480 - in trunk/libs/spirit/example/scheme: example/scheme scheme test/utree utree utree/detail
From: joel_at_[hidden]
Date: 2010-04-22 04:50:27


Author: djowel
Date: 2010-04-22 04:50:25 EDT (Thu, 22 Apr 2010)
New Revision: 61480
URL: http://svn.boost.org/trac/boost/changeset/61480

Log:
variable args support
Added:
   trunk/libs/spirit/example/scheme/example/scheme/more_scheme.scm (contents, props changed)
Text files modified:
   trunk/libs/spirit/example/scheme/example/scheme/some_scheme.scm | 5
   trunk/libs/spirit/example/scheme/scheme/compiler.hpp | 117 ++++++++++++++++------
   trunk/libs/spirit/example/scheme/scheme/interpreter.hpp | 1
   trunk/libs/spirit/example/scheme/scheme/intrinsics.hpp | 204 ++++++++++++++++++++++++---------------
   trunk/libs/spirit/example/scheme/test/utree/utree_test.cpp | 14 ++
   trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp | 66 +++++++-----
   trunk/libs/spirit/example/scheme/utree/utree.hpp | 19 +++
   7 files changed, 287 insertions(+), 139 deletions(-)

Added: trunk/libs/spirit/example/scheme/example/scheme/more_scheme.scm
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/example/scheme/more_scheme.scm 2010-04-22 04:50:25 EDT (Thu, 22 Apr 2010)
@@ -0,0 +1,24 @@
+(define (apply x f) (display (f x)))
+
+(apply 5 (lambda (x) (* x 5)))
+
+(display (quote (1 2 3 4 5)))
+
+(display (quote ()))
+
+
+(define for_each
+ lambda (x f)
+ f()
+
+
+(define (display-all . args)
+ (display args))
+
+(display-all 123 456 999 666)
+
+(display (+ 1 2 3 4 5 6))
+
+(define (display-all first . rest) (display first) (display rest))
+
+(display-all 123 456 999 666)
\ No newline at end of file

Modified: trunk/libs/spirit/example/scheme/example/scheme/some_scheme.scm
==============================================================================
--- trunk/libs/spirit/example/scheme/example/scheme/some_scheme.scm (original)
+++ trunk/libs/spirit/example/scheme/example/scheme/some_scheme.scm 2010-04-22 04:50:25 EDT (Thu, 22 Apr 2010)
@@ -1 +1,4 @@
-(display (xxx 2 3 4 5))
\ No newline at end of file
+(define (display-all . args)
+ (display args))
+
+(display-all 123 456 999 666)
\ No newline at end of file

Modified: trunk/libs/spirit/example/scheme/scheme/compiler.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme/compiler.hpp (original)
+++ trunk/libs/spirit/example/scheme/scheme/compiler.hpp 2010-04-22 04:50:25 EDT (Thu, 22 Apr 2010)
@@ -10,10 +10,10 @@
 #include <vector>
 #include <map>
 #include <exception>
-#include <cstdlib>
 
 #include <boost/bind.hpp>
 #include <boost/tuple/tuple.hpp>
+#include <boost/lexical_cast.hpp>
 #include <scheme/intrinsics.hpp>
 #include <scheme/interpreter.hpp>
 #include <input/parse_sexpr.hpp>
@@ -27,6 +27,7 @@
 
     struct compilation_error : std::exception
     {
+ ~compilation_error() throw() {}
         virtual const char* what() const throw()
         {
             return "scheme: Compilation error.";
@@ -35,6 +36,7 @@
 
     struct identifier_expected : scheme_exception
     {
+ ~identifier_expected() throw() {}
         virtual const char* what() const throw()
         {
             return "scheme: Identifier expected.";
@@ -46,6 +48,7 @@
         std::string msg;
         identifier_not_found(std::string const& id)
           : msg("scheme: Identifier (" + id + ") not found.") {}
+ ~identifier_not_found() throw() {}
 
         virtual const char* what() const throw()
         {
@@ -58,6 +61,7 @@
         std::string msg;
         duplicate_identifier(std::string const& id)
           : msg("scheme: Duplicate identifier (" + id + ").") {}
+ ~duplicate_identifier() throw() {}
 
         virtual const char* what() const throw()
         {
@@ -77,9 +81,9 @@
             else
                 msg += std::string(" Expecting ");
 
- char buff[std::numeric_limits<int>::digits10];
- msg += std::string(ltoa(arity, buff, 10)) + " arguments.";
+ msg += boost::lexical_cast<std::string>(arity) + " arguments.";
         }
+ ~incorrect_arity() throw() {}
 
         virtual const char* what() const throw()
         {
@@ -95,6 +99,7 @@
             // $$$ TODO: add got to message $$$
             msg = "scheme: Function application expected";
         }
+ ~function_application_expected() throw() {}
 
         virtual const char* what() const throw()
         {
@@ -227,27 +232,35 @@
 
         function make_lambda(
             std::vector<std::string> const& args,
+ bool fixed_arity,
             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), 0, false);
- return protect(compile(body, local_env, fragments, line, source_file));
+ {
+ if (!fixed_arity && (args.size() - 1) == i)
+ local_env.define(args[i], boost::bind(varg, i), 0, false);
+ else
+ local_env.define(args[i], boost::bind(arg, i), 0, false);
+ }
+ return protect(compile(body[0], local_env, fragments, line, source_file));
         }
 
         function define_function(
             std::string const& name,
- std::vector<std::string> const& args,
+ std::vector<std::string>& args,
+ bool fixed_arity,
             utree const& body) const
         {
             try
             {
                 if (env.defined(name))
                     throw duplicate_identifier(name);
+
                 fragments.push_back(function());
                 function& f = fragments.back();
- env.define(name, external_function(f), args.size(), true); // $$$ fixed arity for now $$$
- f = make_lambda(args, body)(); // unprotect (evaluate returns a function)
+ env.define(name, external_function(f), args.size(), fixed_arity);
+ f = make_lambda(args, fixed_arity, body)(); // unprotect (evaluate returns a function)
                 return f;
             }
             catch (compilation_error const&)
@@ -257,9 +270,10 @@
             }
         }
 
- template <typename Iterator>
- function operator()(boost::iterator_range<Iterator> const& range) const
+ function operator()(utree::const_range const& range) const
         {
+ typedef utree::const_range::iterator iterator;
+
             if (range.begin()->which() != utree_type::symbol_type)
                 throw function_application_expected(*range.begin());
 
@@ -267,7 +281,7 @@
 
             if (name == "quote")
             {
- Iterator i = range.begin(); ++i;
+ iterator i = range.begin(); ++i;
                 return scheme::val(*i);
             }
 
@@ -275,16 +289,24 @@
             {
                 std::string fname;
                 std::vector<std::string> args;
+ bool fixed_arity = true;
 
- Iterator i = range.begin(); ++i;
+ iterator i = range.begin(); ++i;
                 if (i->which() == utree_type::list_type)
                 {
                     // (define (f x) ...body...)
                     utree const& decl = *i++;
- Iterator di = decl.begin();
+ iterator di = decl.begin();
                     fname = get_symbol(*di++);
                     while (di != decl.end())
- args.push_back(get_symbol(*di++));
+ {
+ std::string sym = get_symbol(*di++);
+ if (sym == ".")
+ // check that . is one pos behind the last arg
+ fixed_arity = false;
+ else
+ args.push_back(sym);
+ }
                 }
                 else
                 {
@@ -296,51 +318,79 @@
                         && get_symbol((*i)[0]) == "lambda")
                     {
                         utree const& arg_names = (*i)[1];
- Iterator ai = arg_names.begin();
+ iterator ai = arg_names.begin();
                         while (ai != arg_names.end())
- args.push_back(get_symbol(*ai++));
-
- return define_function(fname, args, (*i)[2]);
+ {
+ std::string sym = get_symbol(*ai++);
+ if (sym == ".")
+ // check that . is one pos behind the last arg
+ fixed_arity = false;
+ else
+ args.push_back(sym);
+ };
+
+ iterator bi = i->begin(); ++bi; ++bi; // (*i)[2]
+ utree body(utree::const_range(bi, i->end()), shallow);
+ return define_function(fname, args, fixed_arity, body);
                     }
                 }
 
- return define_function(fname, args, *i);
+ utree body(utree::const_range(i, range.end()), shallow);
+ return define_function(fname, args, fixed_arity, body);
             }
 
             if (name == "lambda")
             {
                 // (lambda (x) ...body...)
- Iterator i = range.begin(); ++i;
+ iterator i = range.begin(); ++i;
                 utree const& arg_names = *i++;
- Iterator ai = arg_names.begin();
+ iterator ai = arg_names.begin();
                 std::vector<std::string> args;
+ bool fixed_arity = true;
+
                 while (ai != arg_names.end())
- args.push_back(get_symbol(*ai++));
- return make_lambda(args, *i);
+ {
+ std::string sym = get_symbol(*ai++);
+ if (sym == ".")
+ // check that . is one pos behind the last arg
+ fixed_arity = false;
+ else
+ args.push_back(sym);
+ }
+
+ utree body(utree::const_range(i, range.end()), shallow);
+ return make_lambda(args, fixed_arity, body);
             }
 
             // (f x)
             boost::tuple<compiled_function*, int, bool> r = env.find(name);
             if (boost::get<0>(r))
             {
+ compiled_function* cf = boost::get<0>(r);
+ int arity = boost::get<1>(r);
+ bool fixed_arity = boost::get<2>(r);
+
                 actor_list flist;
- Iterator i = range.begin(); ++i;
- for (; i != range.end(); ++i)
+ iterator i = range.begin(); ++i;
+ int size = 0;
+ for (; i != range.end(); ++i, ++size)
+ {
                     flist.push_back(
                         compile(*i, env, fragments, line, source_file));
+ }
 
                 // Arity check
- if (!boost::get<2>(r)) // non-fixed arity
+ if (!fixed_arity) // non-fixed arity
                 {
- if (int(flist.size()) < boost::get<1>(r))
- throw incorrect_arity(name, boost::get<1>(r), false);
+ if (size < arity)
+ throw incorrect_arity(name, arity, false);
                 }
                 else // fixed arity
                 {
- if (int(flist.size()) != boost::get<1>(r))
- throw incorrect_arity(name, boost::get<1>(r), true);
+ if (size != arity)
+ throw incorrect_arity(name, arity, true);
                 }
- return (*boost::get<0>(r))(flist);
+ return (*cf)(flist);
             }
             else
             {
@@ -426,12 +476,17 @@
     void build_basic_environment(environment& env)
     {
         env.define("if", if_, 3, true);
+ env.define("begin", block, 1, false);
         env.define("display", display, 1, true);
+ env.define("front", front, 1, true);
+ env.define("back", back, 1, true);
+ env.define("rest", rest, 1, true);
         env.define("<", less_than, 2, true);
         env.define("<=", less_than_equal, 2, true);
         env.define("+", plus, 2, false);
         env.define("-", minus, 2, false);
         env.define("*", times, 2, false);
+ env.define("/", divide, 2, false);
     }
 
     ///////////////////////////////////////////////////////////////////////////

Modified: trunk/libs/spirit/example/scheme/scheme/interpreter.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme/interpreter.hpp (original)
+++ trunk/libs/spirit/example/scheme/scheme/interpreter.hpp 2010-04-22 04:50:25 EDT (Thu, 22 Apr 2010)
@@ -366,6 +366,7 @@
 
         utree eval(args_type args) const
         {
+ BOOST_ASSERT(!elements.empty());
             actor_list::const_iterator i = elements.begin();
             utree result = (*i++)(args);
             boost::iterator_range<actor_list::const_iterator>

Modified: trunk/libs/spirit/example/scheme/scheme/intrinsics.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme/intrinsics.hpp (original)
+++ trunk/libs/spirit/example/scheme/scheme/intrinsics.hpp 2010-04-22 04:50:25 EDT (Thu, 22 Apr 2010)
@@ -51,122 +51,166 @@
     if_composite const if_ = if_composite();
 
     ///////////////////////////////////////////////////////////////////////////
- // less_than
+ // list
     ///////////////////////////////////////////////////////////////////////////
- struct less_than_function
- : binary_function<less_than_function>
+ struct list_function : actor<list_function>
     {
- less_than_function(function const& a, function const& b)
- : base_type(a, b) {}
+ actor_list elements;
+ list_function(actor_list const& elements)
+ : elements(elements)
+ {
+ BOOST_FOREACH(function const& element, elements)
+ {
+ BOOST_ASSERT(!element.empty());
+ }
+ }
 
- typedef utree result_type;
- utree eval(utree const& a, utree const& b) const
+ utree eval(args_type args) const
         {
- return a < b;
+ utree result;
+ BOOST_FOREACH(function const& element, elements)
+ {
+ result.push_back(element(args));
+ }
+ return result;
         }
     };
 
- 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>
+ struct list_composite : composite<list_composite>
     {
- 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
+ function compose(actor_list const& elements) const
         {
- return a <= b;
+ return function(list_function(elements));
         }
     };
 
- 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
+ list_composite const list = list_composite();
 
     ///////////////////////////////////////////////////////////////////////////
- // plus
+ // block
     ///////////////////////////////////////////////////////////////////////////
- struct plus_function : nary_function<plus_function>
+ struct block_function : actor<block_function>
     {
- plus_function(actor_list const& elements)
- : base_type(elements) {}
+ actor_list elements;
+ block_function(actor_list const& elements)
+ : elements(elements)
+ {
+ BOOST_FOREACH(function const& element, elements)
+ {
+ BOOST_ASSERT(!element.empty());
+ }
+ }
 
- bool eval(utree& result, utree const& element) const
+ utree eval(args_type args) const
         {
- result = result + element;
- return true;
+ BOOST_ASSERT(!elements.empty());
+ actor_list::const_iterator end = elements.end();
+ boost::iterator_range<actor_list::const_iterator>
+ head_elements(elements.begin(), end--);
+ BOOST_FOREACH(function const& element, head_elements)
+ {
+ element(args);
+ }
+ return (*end)(args);
         }
     };
 
- struct plus_composite : nary_composite<plus_function> {};
- plus_composite const plus = plus_composite();
-
- ///////////////////////////////////////////////////////////////////////////
- // minus
- ///////////////////////////////////////////////////////////////////////////
- struct minus_function : nary_function<minus_function>
+ struct block_composite : composite<block_composite>
     {
- minus_function(actor_list const& elements)
- : base_type(elements) {}
-
- bool eval(utree& result, utree const& element) const
+ function compose(actor_list const& elements) const
         {
- result = result - element;
- return true;
+ return function(block_function(elements));
         }
     };
 
- struct minus_composite : nary_composite<minus_function> {};
- minus_composite const minus = minus_composite();
+ block_composite const block = block_composite();
 
     ///////////////////////////////////////////////////////////////////////////
- // times
+ // SCHEME_UNARY_INTRINSIC
     ///////////////////////////////////////////////////////////////////////////
- struct times_function : nary_function<times_function>
- {
- times_function(actor_list const& elements)
- : base_type(elements) {}
+#define SCHEME_UNARY_INTRINSIC(name, expression) \
+ struct name##_function : unary_function<name##_function> \
+ { \
+ name##_function(function const& a) \
+ : base_type(a) {} \
+ \
+ utree eval(utree const& element) const \
+ { \
+ return expression; \
+ } \
+ }; \
+ \
+ struct name##_composite : unary_composite<name##_function> {}; \
+ name##_composite const name = name##_composite() \
+ /***/
 
- bool eval(utree& result, utree const& element) const
- {
- result = result * element;
- return true;
- }
- };
+ ///////////////////////////////////////////////////////////////////////////
+ // SCHEME_BINARY_INTRINSIC
+ ///////////////////////////////////////////////////////////////////////////
+#define SCHEME_BINARY_INTRINSIC(name, expression) \
+ struct name##_function \
+ : binary_function<name##_function> \
+ { \
+ name##_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 expression; \
+ } \
+ }; \
+ \
+ struct name##_composite \
+ : binary_composite<name##_function> {}; \
+ \
+ name##_composite const name = name##_composite() \
+ /***/
 
- struct times_composite : nary_composite<times_function> {};
- times_composite const times = times_composite();
+ ///////////////////////////////////////////////////////////////////////////
+ // SCHEME_NARY_INTRINSIC
+ ///////////////////////////////////////////////////////////////////////////
+#define SCHEME_NARY_INTRINSIC(name, expression) \
+ struct name##_function : nary_function<name##_function> \
+ { \
+ name##_function(actor_list const& elements) \
+ : base_type(elements) {} \
+ \
+ bool eval(utree& result, utree const& element) const \
+ { \
+ expression; \
+ return true; \
+ } \
+ }; \
+ \
+ struct name##_composite : nary_composite<name##_function> {}; \
+ name##_composite const name = name##_composite() \
+ /***/
 
     ///////////////////////////////////////////////////////////////////////////
- // display
+ // unary intrinsics
     ///////////////////////////////////////////////////////////////////////////
- struct display_function : unary_function<display_function>
- {
- display_function(function const& a)
- : base_type(a) {}
+ SCHEME_UNARY_INTRINSIC(display, (std::cout << element, utree()));
+ SCHEME_UNARY_INTRINSIC(front, element.front());
+ SCHEME_UNARY_INTRINSIC(back, element.back());
+ SCHEME_UNARY_INTRINSIC(rest, utree_functions::rest(element));
 
- utree eval(utree const& element) const
- {
- std::cout << element;
- return utree();
- }
- };
+ ///////////////////////////////////////////////////////////////////////////
+ // binary intrinsics
+ ///////////////////////////////////////////////////////////////////////////
+ SCHEME_BINARY_INTRINSIC(less_than, a < b);
+ less_than_composite const lt = less_than; // synonym
 
- struct display_composite : unary_composite<display_function> {};
- display_composite const display = display_composite();
+ SCHEME_BINARY_INTRINSIC(less_than_equal, a <= b);
+ less_than_equal_composite const lte = less_than_equal; // synonym
+
+ ///////////////////////////////////////////////////////////////////////////
+ // nary intrinsics
+ ///////////////////////////////////////////////////////////////////////////
+ SCHEME_NARY_INTRINSIC(plus, result = result + element);
+ SCHEME_NARY_INTRINSIC(minus, result = result - element);
+ SCHEME_NARY_INTRINSIC(times, result = result * element);
+ SCHEME_NARY_INTRINSIC(divide, result = result / element);
 }
 
 #endif

Modified: trunk/libs/spirit/example/scheme/test/utree/utree_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/utree/utree_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/utree/utree_test.cpp 2010-04-22 04:50:25 EDT (Thu, 22 Apr 2010)
@@ -181,6 +181,20 @@
         BOOST_TEST(a[11] == utree(12));
     }
 
+ {
+ // test empty list
+ utree a;
+ a.push_back(1);
+ a.pop_front();
+ check(a, "( )");
+
+ // the other way around
+ utree b;
+ b.push_front(1);
+ b.pop_back();
+ check(b, "( )");
+ }
+
     { // test references
         utree val(123);
         utree ref(boost::ref(val));

Modified: trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp 2010-04-22 04:50:25 EDT (Thu, 22 Apr 2010)
@@ -148,9 +148,6 @@
         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) {}
 
@@ -204,9 +201,6 @@
         node_iterator()
           : node(0), prev(0), curr(nil_node) {}
 
- explicit node_iterator(list::node* node)
- : node(node), prev(node->prev), curr(node->val) {}
-
         node_iterator(list::node* node, list::node* prev)
           : node(node), prev(prev), curr(node ? node->val : nil_node) {}
 
@@ -340,21 +334,39 @@
     inline void list::pop_front()
     {
         BOOST_ASSERT(size != 0);
- node* np = first;
- first = first->next;
- first->prev = 0;
- delete np;
- --size;
+ if (first == last) // there's only one item
+ {
+ delete first;
+ size = 0;
+ first = last = 0;
+ }
+ else
+ {
+ 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;
+ if (first == last) // there's only one item
+ {
+ delete first;
+ size = 0;
+ first = last = 0;
+ }
+ else
+ {
+ node* np = last;
+ last = last->prev;
+ last->next = 0;
+ delete np;
+ --size;
+ }
     }
 
     inline list::node* list::erase(node* pos)
@@ -448,10 +460,10 @@
                     return f(x.d);
 
                 case type::list_type:
- return f(list_range(iterator(x.l.first), iterator(0, x.l.last)));
+ return f(list_range(iterator(x.l.first, 0), iterator(0, x.l.last)));
 
                 case type::range_type:
- return f(list_range(iterator(x.r.first), iterator(0, x.r.last)));
+ return f(list_range(iterator(x.r.first, 0), iterator(0, x.r.last)));
 
                 case type::string_type:
                     return f(utf8_string_range(x.s.str(), x.s.size()));
@@ -504,12 +516,12 @@
                 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))));
+ list_range(iterator(x.l.first, 0), iterator(0, x.l.last))));
 
                 case type::range_type:
                     return visit_impl::apply(
                         y, detail::bind<F, list_range>(f,
- list_range(iterator(x.r.first), iterator(0, x.r.last))));
+ list_range(iterator(x.r.first, 0), iterator(0, x.r.last))));
 
                 case type::string_type:
                     return visit_impl::apply(y, detail::bind(
@@ -861,7 +873,7 @@
         else
         {
             l.insert_before(val, pos.node);
- return utree::iterator(pos.node->prev);
+ return utree::iterator(pos.node->prev, pos.node->prev->prev);
         }
     }
 
@@ -943,11 +955,11 @@
         if (get_type() == type::reference_type)
             return p->begin();
         else if (get_type() == type::range_type)
- return iterator(r.first);
+ return iterator(r.first, 0);
 
         // otherwise...
         ensure_list_type();
- return iterator(l.first);
+ return iterator(l.first, 0);
     }
 
     inline utree::iterator utree::end()
@@ -967,11 +979,11 @@
         if (get_type() == type::reference_type)
             return p->ref_begin();
         else if (get_type() == type::range_type)
- return ref_iterator(r.first);
+ return ref_iterator(r.first, 0);
 
         // otherwise...
         ensure_list_type();
- return ref_iterator(l.first);
+ return ref_iterator(l.first, 0);
     }
 
     inline utree::ref_iterator utree::ref_end()
@@ -991,11 +1003,11 @@
         if (get_type() == type::reference_type)
             return ((utree const*)p)->begin();
         else if (get_type() == type::range_type)
- return const_iterator(r.first);
+ return const_iterator(r.first, 0);
 
         // otherwise...
         BOOST_ASSERT(get_type() == type::list_type);
- return const_iterator(l.first);
+ return const_iterator(l.first, 0);
     }
 
     inline utree::const_iterator utree::end() const

Modified: trunk/libs/spirit/example/scheme/utree/utree.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree/utree.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree/utree.hpp 2010-04-22 04:50:25 EDT (Thu, 22 Apr 2010)
@@ -356,4 +356,23 @@
 
 #include <utree/detail/utree_detail2.hpp>
 
+// $$$ move this in its own file $$$
+namespace scheme { namespace utree_functions
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Extra functions
+ ///////////////////////////////////////////////////////////////////////////
+ inline utree rest(utree& x)
+ {
+ utree::iterator i = x.begin(); ++i;
+ return utree(utree::range(i, x.end()), shallow);
+ }
+
+ inline utree rest(utree const& x)
+ {
+ utree::const_iterator i = x.begin(); ++i;
+ return utree(utree::const_range(i, x.end()), shallow);
+ }
+}}
+
 #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