Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61549 - in trunk/libs/spirit/example/scheme: . scheme test test/utree utree utree/detail
From: joel_at_[hidden]
Date: 2010-04-24 20:55:23


Author: djowel
Date: 2010-04-24 20:55:21 EDT (Sat, 24 Apr 2010)
New Revision: 61549
URL: http://svn.boost.org/trac/boost/changeset/61549

Log:
various updates
Properties modified:
   trunk/libs/spirit/example/scheme/test/ (props changed)
Text files modified:
   trunk/libs/spirit/example/scheme/scheme/interpreter.hpp | 15 +++++-
   trunk/libs/spirit/example/scheme/test/qi_interpreter.cpp | 94 ++++++++++++++++++++++++++++++++++++++++
   trunk/libs/spirit/example/scheme/test/utree/utree_test.cpp | 22 ++++++++
   trunk/libs/spirit/example/scheme/todo.txt | 1
   trunk/libs/spirit/example/scheme/utree/detail/utree_detail1.hpp | 11 ++++
   trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp | 49 ++++++++++++++++++++
   trunk/libs/spirit/example/scheme/utree/operators.hpp | 11 ++++
   trunk/libs/spirit/example/scheme/utree/utree.hpp | 64 +++++++++++++++++++++++++-
   8 files changed, 257 insertions(+), 10 deletions(-)

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-24 20:55:21 EDT (Sat, 24 Apr 2010)
@@ -17,6 +17,11 @@
 
 #define SCHEME_COMPOSITE_LIMIT 10
 
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4018)
+#endif
+
 namespace scheme
 {
 ///////////////////////////////////////////////////////////////////////////////
@@ -70,7 +75,7 @@
 
         template <std::size_t n>
         static scope
- get_range(boost::array<utree, n> const& array)
+ get_range(boost::array<utree, n>& array)
         {
             return scope(array.begin(), array.end());
         }
@@ -121,7 +126,7 @@
         utree val;
         value_function(utree const& val) : val(val) {}
 
- utree eval(scope /*env*/) const
+ utree eval(scope const& /*env*/) const
         {
             return utree(boost::ref(val));
         }
@@ -506,7 +511,7 @@
                 {
                     fargs[i++] = element(env);
                 }
- utree const* fi = fargs.get();
+ utree* fi = fargs.get();
                 return f.get()(scope(fi, fi+elements.size(), outer));
             }
             else
@@ -542,4 +547,8 @@
     };
 }
 
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
 #endif

Modified: trunk/libs/spirit/example/scheme/test/qi_interpreter.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/qi_interpreter.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/qi_interpreter.cpp 2010-04-24 20:55:21 EDT (Sat, 24 Apr 2010)
@@ -11,9 +11,103 @@
 #include <input/parse_sexpr_impl.hpp>
 #include <scheme/compiler.hpp>
 #include <utree/io.hpp>
+#include <boost/spirit/include/qi.hpp>
 
 namespace scheme
 {
+ ///////////////////////////////////////////////////////////////////////////
+ // parser
+ ///////////////////////////////////////////////////////////////////////////
+ using boost::spirit::unused;
+ namespace qi = boost::spirit::qi;
+ namespace spirit = boost::spirit;
+
+ typedef boost::iterator_range<char const*> source_type;
+
+ template <typename Parser, bool no_attr>
+ struct qi_parser_function
+ : actor<qi_parser_function<Parser, no_attr> >
+ {
+ Parser p;
+ qi_parser_function(Parser const& p)
+ : p(p) {}
+
+ utree eval(scope const& env) const
+ {
+ // the source input
+ source_type rng = env[0].get<source_type>();
+ char const* iter = rng.begin();
+
+ // the skipper
+ utree const& skipper = env[1];
+
+ // do a pre-skip
+ while (skipper.eval(env) == true)
+ ;
+
+ // the attribute
+ utree& attribute = env[2];
+ bool r = false;
+ if (r = p.parse(iter, rng.end(), unused, unused, attribute))
+ env[0] = source_type(iter, rng.end());
+
+ return r;
+ }
+ };
+
+ template <typename Parser>
+ struct qi_parser_function<Parser, true> // unused attribute
+ : actor<qi_parser_function<Parser, true> >
+ {
+ Parser p;
+ qi_parser_function(Parser const& p)
+ : p(p) {}
+
+ utree eval(scope const& env) const
+ {
+ // the source input
+ source_type rng = env[0].get<source_type>();
+ char const* iter = rng.begin();
+
+ // the skipper
+ utree const& skipper = env[1];
+
+ // do a pre-skip
+ while (skipper.eval(env) == true)
+ ;
+
+ bool r = false;
+ if (r = p.parse(iter, rng.end(), unused, unused, unused))
+ env[0] = source_type(iter, rng.end());
+
+ return r;
+ }
+ };
+
+ struct qi_parser
+ {
+ typedef function result_type;
+
+ template <typename Expression>
+ function operator()(Expression const& expr) const
+ {
+ typedef typename
+ boost::spirit::result_of::compile<
+ qi::domain, Expression>::type
+ parser_type;
+
+ typedef boost::is_same<
+ typename spirit::traits::attribute_of<parser_type>::type,
+ spirit::unused_type>
+ is_unused;
+
+ return function(qi_parser_function<parser_type, is_unused::value>(
+ qi::compile<qi::domain>(expr)));
+ }
+ };
+
+ qi_parser const primitive_parser = {};
+ function const space = primitive_parser(qi::space);
 }
 
 ///////////////////////////////////////////////////////////////////////////////

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-24 20:55:21 EDT (Sat, 24 Apr 2010)
@@ -12,6 +12,7 @@
 #include <utree/io.hpp>
 #include <iostream>
 #include <sstream>
+#include <cstdlib>
 
 inline void check(scheme::utree const& val, std::string expected)
 {
@@ -54,6 +55,12 @@
     }
 
     {
+ // single element string
+ utree val('x');
+ check(val, "\"x\"");
+ }
+
+ {
         utree val(123.456);
         check(val, "123.456");
     }
@@ -303,12 +310,13 @@
     }
 
     {
+ // shallow string ranges
+
         using scheme::utf8_string_range;
         using scheme::shallow;
 
- // shallow string ranges
         char const* s = "Hello, World";
- utree val(utf8_string_range(s, s + std::strlen(s)), shallow);
+ utree val(utf8_string_range(s, s + strlen(s)), shallow);
         check(val, "\"Hello, World\"");
 
         utf8_string_range r = val.get<utf8_string_range>();
@@ -317,5 +325,15 @@
         check(val, "\"ello, Worl\"");
     }
 
+ {
+ // any pointer
+
+ using scheme::any_ptr;
+
+ int n = 123;
+ utree up = any_ptr(&n);
+ BOOST_TEST(*up.get<int*>() == 123);
+ }
+
     return boost::report_errors();
 }

Modified: trunk/libs/spirit/example/scheme/todo.txt
==============================================================================
--- trunk/libs/spirit/example/scheme/todo.txt (original)
+++ trunk/libs/spirit/example/scheme/todo.txt 2010-04-24 20:55:21 EDT (Sat, 24 Apr 2010)
@@ -2,3 +2,4 @@
 - allow scheme-ish #t and #f
 - write parser and generator for binary on disk representation of sexpr
 - implement quote in sexpr grammar (e.g. 'sym '(1 2 3 4 5))
+- investigate storing and retrieving polymorphic pointers from utree

Modified: trunk/libs/spirit/example/scheme/utree/detail/utree_detail1.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree/detail/utree_detail1.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree/detail/utree_detail1.hpp 2010-04-24 20:55:21 EDT (Sat, 24 Apr 2010)
@@ -13,7 +13,9 @@
 {
     template <typename UTreeX, typename UTreeY>
     struct visit_impl;
+
     struct index_impl;
+
     template <typename T>
     struct get_impl;
 
@@ -74,6 +76,15 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
+ // A void* plus type_info
+ ///////////////////////////////////////////////////////////////////////////
+ struct void_ptr
+ {
+ void* p;
+ std::type_info const* i;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
     // 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

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-24 20:55:21 EDT (Sat, 24 Apr 2010)
@@ -13,6 +13,10 @@
 # pragma warning(disable: 4800)
 #endif
 
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/utility/enable_if.hpp>
+
 namespace scheme { namespace detail
 {
     inline char& fast_string::info()
@@ -480,6 +484,9 @@
                 case type::reference_type:
                     return apply(*x.p, f);
 
+ case type::any_type:
+ return f(any_ptr(x.v.p, x.v.i));
+
                 case type::function_type:
                     return f(*x.pf);
             }
@@ -545,6 +552,10 @@
                 case type::reference_type:
                     return apply(*x.p, y, f);
 
+ case type::any_type:
+ return visit_impl::apply(
+ y, detail::bind(f, any_ptr(x.v.p, x.v.i)));
+
                 case type::function_type:
                     return visit_impl::apply(y, detail::bind(f, *x.pf));
 
@@ -606,6 +617,13 @@
         set_type(type::bool_type);
     }
 
+ inline utree::utree(char c)
+ {
+ // char constructs a single element string
+ s.construct(&c, &c+1);
+ set_type(type::string_type);
+ }
+
     inline utree::utree(unsigned int i) : i(i)
     {
         set_type(type::int_type);
@@ -652,6 +670,13 @@
         set_type(type::reference_type);
     }
 
+ inline utree::utree(any_ptr const& p)
+ {
+ v.p = p.p;
+ v.i = p.i;
+ set_type(type::any_type);
+ }
+
     template <typename F>
     inline utree::utree(stored_function<F> const& pf)
       : pf(new stored_function<F>(pf))
@@ -1214,6 +1239,9 @@
             case type::reference_type:
                 p = other.p;
                 break;
+ case type::any_type:
+ v = other.v;
+ break;
             case type::range_type:
                 r = other.r;
                 break;
@@ -1260,7 +1288,7 @@
         To dispatch(From const& val, boost::mpl::false_) const
         {
             // From is NOT convertible to To !!!
- BOOST_ASSERT(false);
+ throw std::bad_cast();
             return To();
         }
 
@@ -1278,6 +1306,25 @@
     };
 
     template <typename T>
+ struct utree_cast<T*>
+ {
+ typedef T* result_type;
+
+ template <typename From>
+ T* operator()(From const& val) const
+ {
+ // From is NOT convertible to T !!!
+ throw std::bad_cast();
+ return 0;
+ }
+
+ T* operator()(any_ptr const& p) const
+ {
+ return p.get<T*>();
+ }
+ };
+
+ template <typename T>
     inline T utree::get() const
     {
         return utree::visit(*this, utree_cast<T>());

Modified: trunk/libs/spirit/example/scheme/utree/operators.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree/operators.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree/operators.hpp 2010-04-24 20:55:21 EDT (Sat, 24 Apr 2010)
@@ -177,6 +177,12 @@
             return false; // no less than comparison for nil
         }
 
+ bool operator()(any_ptr const& a, any_ptr const& b) const
+ {
+ BOOST_ASSERT(false);
+ return false; // no less than comparison for any_ptr
+ }
+
         bool operator()(function_base const& a, function_base const& b) const
         {
             BOOST_ASSERT(false);
@@ -251,6 +257,11 @@
             (*this)(')');
         }
 
+ void operator()(any_ptr const& p) const
+ {
+ return (*this)("<pointer>");
+ }
+
         void operator()(function_base const& pf) const
         {
             return (*this)("<function>");

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-24 20:55:21 EDT (Sat, 24 Apr 2010)
@@ -12,12 +12,17 @@
 #include <algorithm>
 #include <string>
 #include <ostream>
+#include <typeinfo>
 
 #include <boost/assert.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/iterator/iterator_facade.hpp>
 #include <boost/range/iterator_range.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/type_traits/is_polymorphic.hpp>
+#include <boost/utility/enable_if.hpp>
 #include <boost/ref.hpp>
+
 #include <utree/detail/utree_detail1.hpp>
 
 #if defined(BOOST_MSVC)
@@ -48,6 +53,7 @@
             list_type,
             range_type,
             reference_type,
+ any_type,
             function_type
         };
     };
@@ -163,6 +169,52 @@
     shallow_tag const shallow = {};
 
     ///////////////////////////////////////////////////////////////////////////
+ // A void* plus type_info
+ ///////////////////////////////////////////////////////////////////////////
+ class any_ptr
+ {
+ public:
+
+ template <typename Ptr>
+ typename boost::disable_if<
+ boost::is_polymorphic<
+ typename boost::remove_pointer<Ptr>::type>,
+ Ptr>::type
+ get() const
+ {
+ if (*i == typeid(Ptr))
+ {
+ return static_cast<Ptr>(p);
+ }
+ throw std::bad_cast();
+ }
+
+ template <typename T>
+ any_ptr(T* p)
+ : p(p), i(&typeid(T*))
+ {}
+
+ friend bool operator==(any_ptr const& a, any_ptr const& b)
+ {
+ return (a.p == b.p) && (*a.i == *b.i);
+ }
+
+ private:
+
+ // constructor is private
+ any_ptr(void* p, std::type_info const* i)
+ : p(p), i(i) {}
+
+ template <typename UTreeX, typename UTreeY>
+ friend struct detail::visit_impl;
+
+ friend class utree;
+
+ void* p;
+ std::type_info const* i;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
     // The main utree (Universal Tree) class
     // The utree is a hierarchical, dynamic type that can store:
     // - a nil
@@ -176,6 +228,7 @@
     // - a (doubly linked) list of utree
     // - an iterator_range of list::iterator
     // - a reference to a utree
+ // - a pointer or reference to any type
     // - a function
     //
     // The utree has minimal memory footprint. The data structure size is
@@ -201,6 +254,7 @@
 
         utree();
         utree(bool b);
+ utree(char c);
         utree(unsigned int i);
         utree(int i);
         utree(double d);
@@ -208,6 +262,7 @@
         utree(char const* str, std::size_t len);
         utree(std::string const& str);
         utree(boost::reference_wrapper<utree> ref);
+ utree(any_ptr const& p);
 
         template <typename Iter>
         utree(boost::iterator_range<Iter> r);
@@ -347,6 +402,7 @@
             detail::list l;
             detail::range r;
             detail::string_range sr;
+ detail::void_ptr v;
             bool b;
             int i;
             double d;
@@ -358,14 +414,14 @@
     ///////////////////////////////////////////////////////////////////////////
     // The scope
     ///////////////////////////////////////////////////////////////////////////
- class scope : public boost::iterator_range<utree const*>
+ class scope : public boost::iterator_range<utree*>
     {
     public:
 
- scope(utree const* first = 0,
- utree const* last = 0,
+ scope(utree* first = 0,
+ utree* last = 0,
             scope const* parent = 0)
- : boost::iterator_range<utree const*>(first, last),
+ : boost::iterator_range<utree*>(first, last),
             parent(parent),
             depth(parent? parent->depth + 1 : 0)
         {}


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