Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61151 - in trunk/libs/spirit/example/scheme: detail test
From: joel_at_[hidden]
Date: 2010-04-09 03:34:56


Author: djowel
Date: 2010-04-09 03:34:55 EDT (Fri, 09 Apr 2010)
New Revision: 61151
URL: http://svn.boost.org/trac/boost/changeset/61151

Log:
+ bug fixes
+ working define function
Text files modified:
   trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp | 33 +++++--
   trunk/libs/spirit/example/scheme/test/scheme.cpp | 155 ++++++++++++++++++++++++++++++++++++---
   trunk/libs/spirit/example/scheme/test/utree_test.cpp | 96 +++++++++++++-----------
   3 files changed, 216 insertions(+), 68 deletions(-)

Modified: trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp (original)
+++ trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp 2010-04-09 03:34:55 EDT (Fri, 09 Apr 2010)
@@ -127,8 +127,11 @@
         node_iterator()
           : node(0) {}
 
- explicit node_iterator(list::node* p)
- : node(p) {}
+ explicit node_iterator(list::node* node)
+ : node(node), prev(node->prev) {}
+
+ node_iterator(list::node* node, list::node* prev)
+ : node(node), prev(prev) {}
 
     private:
 
@@ -137,12 +140,20 @@
 
         void increment()
         {
- node = node->next;
+ if (node != 0) // not at end
+ {
+ prev = node;
+ node = node->next;
+ }
         }
 
         void decrement()
         {
- node = node->prev;
+ if (prev != 0) // not at begin
+ {
+ node = prev;
+ prev = prev->prev;
+ }
         }
 
         bool equal(node_iterator const& other) const
@@ -156,6 +167,7 @@
         }
 
         list::node* node;
+ list::node* prev;
     };
 
     inline void list::free()
@@ -350,7 +362,7 @@
                     return f(x.d);
 
                 case type::list_type:
- return f(list_range(iterator(x.l.first), iterator(0)));
+ 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()));
@@ -403,7 +415,7 @@
                 case type::list_type:
                     return visit_impl::apply(
                         y, detail::bind<F, list_range>(f,
- list_range(iterator(x.l.first), iterator(0))));
+ list_range(iterator(x.l.first), iterator(0, x.l.last))));
 
                 case type::string_type:
                     return visit_impl::apply(y, detail::bind(
@@ -683,7 +695,7 @@
         if (get_type() == type::reference_type)
             return p->insert(pos, val);
         ensure_list_type();
- if (pos.node == l.last)
+ if (pos == end())
         {
             push_back(val);
             return begin();
@@ -756,7 +768,8 @@
         if (get_type() == type::reference_type)
             return p->erase(pos);
         BOOST_ASSERT(get_type() == type::list_type);
- return iterator(l.erase(pos.node));
+ 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)
@@ -781,7 +794,7 @@
         if (get_type() == type::reference_type)
             return p->end();
         ensure_list_type();
- return iterator(l.last);
+ return iterator(0, l.last);
     }
 
     inline utree::const_iterator utree::begin() const
@@ -797,7 +810,7 @@
         if (get_type() == type::reference_type)
             return ((utree const*)p)->end();
         BOOST_ASSERT(get_type() == type::list_type);
- return const_iterator(l.last);
+ return const_iterator(0, l.last);
     }
 
     inline bool utree::empty() const

Modified: trunk/libs/spirit/example/scheme/test/scheme.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/scheme.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/scheme.cpp 2010-04-09 03:34:55 EDT (Fri, 09 Apr 2010)
@@ -26,6 +26,15 @@
 namespace scheme
 {
 ///////////////////////////////////////////////////////////////////////////////
+// Utilities
+///////////////////////////////////////////////////////////////////////////////
+ inline std::string get_symbol(utree const& s)
+ {
+ utf8_symbol_range symbol = s.as<utf8_symbol_range>();
+ return std::string(symbol.begin(), symbol.end());
+ }
+
+///////////////////////////////////////////////////////////////////////////////
 // The runtime interpreter
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -72,6 +81,19 @@
         return function(argument_impl(n));
     }
 
+ struct make_arg
+ {
+ int n;
+ make_arg(int n) : n(n) {}
+
+ typedef function result_type;
+ function operator()(function_list& operands)
+ {
+ // check arity here!
+ return function(argument_impl(n));
+ }
+ };
+
     ///////////////////////////////////////////////////////////////////////////
     // reference
     ///////////////////////////////////////////////////////////////////////////
@@ -129,6 +151,49 @@
 
     make_plus const plus = {};
 
+ ///////////////////////////////////////////////////////////////////////////
+ // fcall
+ ///////////////////////////////////////////////////////////////////////////
+ struct fcall_impl
+ {
+ function f;
+ function_list operands;
+
+ fcall_impl(function const& f, function_list& operands_)
+ : f(f)
+ {
+ // we take ownership of the operands
+ operands_.swap(operands);
+ }
+
+ typedef utree result_type;
+ utree operator()(utree const& args) const
+ {
+ utree fargs;
+ BOOST_FOREACH(function const& operand, operands)
+ {
+ fargs.push_back(operand(args));
+ }
+ return f(fargs);
+ }
+ };
+
+ struct make_fcall
+ {
+ function f;
+ int arity;
+ make_fcall(function const& f, int arity)
+ : f(f), arity(arity) {}
+
+ typedef function result_type;
+ function operator()(function_list& operands)
+ {
+ // $$$ use throw $$$
+ BOOST_ASSERT(operands.size() == arity);
+ return function(fcall_impl(f, operands));
+ }
+ };
+
 ///////////////////////////////////////////////////////////////////////////////
 // The compiler
 ///////////////////////////////////////////////////////////////////////////////
@@ -136,7 +201,8 @@
 
     struct compiler_environment
     {
- compiler_environment() {}
+ compiler_environment(compiler_environment* parent = 0)
+ : parent(parent) {}
 
         void define(std::string const& name, make_function const& def)
         {
@@ -151,9 +217,12 @@
                 i = definitions.find(name);
             if (i != definitions.end())
                 return &i->second;
+ else if (parent != 0)
+ return parent->find(name);
             return 0;
         }
 
+ compiler_environment* parent;
         std::map<std::string, make_function> definitions;
     };
 
@@ -163,9 +232,12 @@
     {
         typedef function result_type;
 
- compiler_environment& env;
- compiler(compiler_environment& env)
- : env(env) {}
+ mutable compiler_environment* env;
+ compiler(compiler_environment* env)
+ : env(env)
+ {
+ BOOST_ASSERT(env != 0);
+ }
 
         function operator()(nil) const
         {
@@ -180,20 +252,71 @@
 
         function operator()(utf8_symbol_range const& str) const
         {
- return function(); // $$$ implement me $$$
+ std::string name(str.begin(), str.end());
+
+ if (make_function* mf = env->find(name))
+ {
+ function_list flist;
+ return (*mf)(flist);
+ }
+ // $$$ throw? $$$
+ return function();
+ }
+
+ void define_function(
+ std::string const& name,
+ std::vector<std::string> const& args,
+ utree const& body) const
+ {
+ compiler_environment local_env(env);
+ for (std::size_t i = 0; i < args.size(); ++i)
+ local_env.define(args[i], make_arg(i));
+ make_fcall mf(compile(body, local_env), args.size());
+ env->define(name, make_function(mf));
         }
 
         template <typename Iterator>
         function operator()(boost::iterator_range<Iterator> const& range) const
         {
- utf8_symbol_range symbol = range.begin()->as<utf8_symbol_range>();
- std::string fname(symbol.begin(), symbol.end());
- if (make_function* mf = env.find(fname))
+ //~ if (range.begin()->which() == utree_type::list_type)
+ //~ BOOST_FOREACH(utree const& x, range)
+ //~ {
+ //~ compile()
+ //~ }
+
+ std::string name(get_symbol(*range.begin()));
+
+ if (name == "define")
+ {
+ Iterator i = range.begin(); ++i;
+ if (i->which() == utree_type::list_type)
+ {
+ // a function
+ utree const& decl = *i++;
+
+
+ Iterator di = decl.begin();
+ std::string fname(get_symbol(*di++));
+ std::vector<std::string> args;
+ while (di != decl.end())
+ args.push_back(get_symbol(*di++));
+ std::cout << "decl: " << decl << " arity:" << args.size() << std::endl;
+
+ define_function(fname, args, *i);
+ return function();
+ }
+ else
+ {
+ // constants
+ }
+ }
+
+ if (make_function* mf = env->find(name))
             {
                 function_list flist;
                 Iterator i = range.begin(); ++i;
                 for (; i != range.end(); ++i)
- flist.push_back(compile(*i, env));
+ flist.push_back(compile(*i, *env));
                 return (*mf)(flist);
             }
 
@@ -203,7 +326,7 @@
 
     function compile(utree const& ast, compiler_environment& env)
     {
- return utree::visit(ast, compiler(env));
+ return utree::visit(ast, compiler(&env));
     }
 
     void build_basic_environment(compiler_environment& env)
@@ -218,6 +341,9 @@
 int main()
 {
     std::string in;
+ scheme::compiler_environment env;
+ scheme::build_basic_environment(env);
+
     while (std::getline(std::cin, in))
     {
         if (in.empty() || in[0] == 'q' || in[0] == 'Q')
@@ -232,11 +358,12 @@
         iterator_type last = in.end();
         if (phrase_parse(first, last, p, ws, result))
         {
- std::cout << "success: ";
- scheme::compiler_environment env;
- scheme::build_basic_environment(env);
+ std::cout << "success: expr =" << result;
             scheme::function f = compile(result, env);
- std::cout << "result: " << f(scheme::utree()) << std::endl;
+ if (f)
+ std::cout << " result: " << f(scheme::utree()) << std::endl;
+ else
+ std::cout << std::endl;
         }
         else
         {

Modified: trunk/libs/spirit/example/scheme/test/utree_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/utree_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/utree_test.cpp 2010-04-09 03:34:55 EDT (Fri, 09 Apr 2010)
@@ -13,6 +13,8 @@
 
 inline std::ostream& println(std::ostream& out, scheme::utree const& val)
 {
+ if (val.which() == scheme::utree_type::list_type)
+ out << "size:" << val.size() << " ";
     out << val << std::endl;
     return out;
 }
@@ -21,67 +23,71 @@
 {
     using scheme::utree;
 
- {
- // test the size
- std::cout << "size of utree is: "
- << sizeof(scheme::utree) << " bytes" << std::endl;
- }
-
- {
- utree val;
- println(std::cout, val);
- }
-
- {
- utree val(true);
- println(std::cout, val);
- }
-
- {
- utree val(123);
- println(std::cout, val);
- }
-
- {
- utree val(123.456);
- println(std::cout, val);
- }
-
- {
- utree val("Hello, World");
- println(std::cout, val);
- utree val2;
- val2 = val;
- println(std::cout, val2);
- utree val3("Hello, World. Chuckie is back!!!");
- val = val3;
- println(std::cout, val);
-
- utree val4("Apple");
- utree val5("Apple");
- BOOST_ASSERT(val4 == val5);
-
- utree val6("ApplePie");
- BOOST_ASSERT(val4 < val6);
- }
+ //~ {
+ //~ // test the size
+ //~ std::cout << "size of utree is: "
+ //~ << sizeof(scheme::utree) << " bytes" << std::endl;
+ //~ }
+
+ //~ {
+ //~ utree val;
+ //~ println(std::cout, val);
+ //~ }
+
+ //~ {
+ //~ utree val(true);
+ //~ println(std::cout, val);
+ //~ }
+
+ //~ {
+ //~ utree val(123);
+ //~ println(std::cout, val);
+ //~ }
+
+ //~ {
+ //~ utree val(123.456);
+ //~ println(std::cout, val);
+ //~ }
+
+ //~ {
+ //~ utree val("Hello, World");
+ //~ println(std::cout, val);
+ //~ utree val2;
+ //~ val2 = val;
+ //~ println(std::cout, val2);
+ //~ utree val3("Hello, World. Chuckie is back!!!");
+ //~ val = val3;
+ //~ println(std::cout, val);
+
+ //~ 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);
         println(std::cout, val);
         println(std::cout, val.front());
 
         utree val3;
         val3.swap(val);
+ BOOST_ASSERT(val3.size() == 3);
         println(std::cout, val);
         val3.swap(val);
         println(std::cout, val);
         val.push_back("another string");
+ BOOST_ASSERT(val.size() == 4);
         println(std::cout, val);
         val.pop_front();
         println(std::cout, val);
@@ -93,12 +99,14 @@
         val.pop_back();
         println(std::cout, val);
         BOOST_ASSERT(val.size() == 3);
- val.erase(val.end());
+ utree::iterator it = val.end(); --it;
+ val.erase(it);
         println(std::cout, val);
         BOOST_ASSERT(val.size() == 2);
 
         val.insert(val.begin(), val2.begin(), val2.end());
         println(std::cout, val);
+ BOOST_ASSERT(val.size() == 4);
     }
 
     {


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