Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61564 - in trunk/libs/spirit/example/scheme: scheme test test/scheme
From: joel_at_[hidden]
Date: 2010-04-25 22:02:49


Author: djowel
Date: 2010-04-25 22:02:48 EDT (Sun, 25 Apr 2010)
New Revision: 61564
URL: http://svn.boost.org/trac/boost/changeset/61564

Log:
updates
Text files modified:
   trunk/libs/spirit/example/scheme/scheme/compiler.hpp | 15 ++-
   trunk/libs/spirit/example/scheme/test/qi_interpreter.cpp | 146 +++++++++++++++++++++++++++++++++++----
   trunk/libs/spirit/example/scheme/test/scheme/scheme_test3.cpp | 14 +++
   3 files changed, 149 insertions(+), 26 deletions(-)

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-25 22:02:48 EDT (Sun, 25 Apr 2010)
@@ -555,11 +555,12 @@
         interpreter(
             Source& in,
             std::string const& source_file = "",
- environment* outer = 0)
- : env(outer)
+ environment* envp = 0)
         {
- if (outer == 0)
+ if (envp == 0)
                 build_basic_environment(env);
+ else
+ env = *envp;
 
             if (input::parse_sexpr_list(in, program, source_file))
             {
@@ -569,11 +570,13 @@
 
         interpreter(
             utree const& program,
- environment* outer = 0)
- : env(outer)
+ environment* envp = 0)
         {
- if (outer == 0)
+ if (envp == 0)
                 build_basic_environment(env);
+ else
+ env = *envp;
+
             compile_all(program, env, flist, fragments);
         }
 

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-25 22:02:48 EDT (Sun, 25 Apr 2010)
@@ -13,7 +13,9 @@
 #include <utree/io.hpp>
 #include <boost/spirit/include/qi.hpp>
 
-namespace scheme
+#include "../../../test/qi/test.hpp"
+
+namespace scheme { namespace qi
 {
     ///////////////////////////////////////////////////////////////////////////
     // parser compiler
@@ -24,6 +26,10 @@
     typedef qi::rule<char const*> skipper_type;
     typedef qi::rule<char const*, utree(), skipper_type> rule_type;
 
+ ///////////////////////////////////////////////////////////////////////////
+ // All rule are stored here. Rules are held in the utree by its id;
+ // i.e. it's index in the vector.
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Rule>
     class rule_fragments
     {
@@ -32,18 +38,21 @@
         rule_fragments() {};
 
         template <typename Expr>
- boost::tuple<Rule const&, int>
- new_rule(Expr const& expr)
+ int new_rule(Expr const& expr)
         {
             rules.push_back(Rule());
             rules.front() = expr;
- return boost::tuple<Rule const&, int>(
- rules.front(), rules.size()-1);
+ return rules.size()-1;
         }
 
         Rule const& get_rule(int id) const
         {
- return rules[i];
+ return rules[id];
+ }
+
+ Rule const& get_rule(utree const& id) const
+ {
+ return rules[id.get<int>()];
         }
 
     private:
@@ -51,6 +60,11 @@
         std::vector<Rule> rules;
     };
 
+ ///////////////////////////////////////////////////////////////////////////
+ // Composes primitive parsers held by index. Handles the compilation of
+ // primitive (nullary) parsers such as int_, double_, alpha, space and all
+ // those that require no arguments.
+ ///////////////////////////////////////////////////////////////////////////
     struct primitive_parser_composite : composite<primitive_parser_composite>
     {
         int id;
@@ -69,43 +83,141 @@
     inline primitive_parser_composite
     make_primitive_parser_composite(Fragments& fragments, Expr const& expr)
     {
- return primitive_parser_composite(
- boost::get<1>(fragments.new_rule(expr)));
+ return primitive_parser_composite(fragments.new_rule(expr));
     }
 
+ ///////////////////////////////////////////////////////////////////////////
+ // Handles the compilation of char_
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Fragments>
- void build_qi_environment(Fragments& fragments, environment& env)
+ struct char_function : actor<char_function<Fragments> >
+ {
+ Fragments& fragments;
+ function a;
+ function b;
+ char_function(
+ Fragments& fragments, function const& a, function const& b)
+ : a(a), b(b), fragments(fragments)
+ {
+ }
+
+ utree eval(utree const& a) const
+ {
+ // $$$ use exceptions here $$$.
+ BOOST_ASSERT(a.which() == utree_type::string_type);
+
+ utf8_string_range a_ = a.get<utf8_string_range>();
+ if (a_.size() == 1)
+ {
+ // char_('x')
+ return fragments.new_rule(qi::char_(a_[0]));
+ }
+ else
+ {
+ // char_("some-regex")
+ return fragments.new_rule(
+ qi::char_(std::string(a_.begin(), a_.end())));
+ }
+ }
+
+ utree eval(utree const& a, utree const& b) const
+ {
+ // $$$ use exceptions here $$$.
+ BOOST_ASSERT(a.which() == utree_type::string_type);
+ BOOST_ASSERT(b.which() == utree_type::string_type);
+
+ utf8_string_range a_ = a.get<utf8_string_range>();
+ utf8_string_range b_ = b.get<utf8_string_range>();
+ // $$$ use exceptions here $$$.
+ BOOST_ASSERT(a_.size() == 1);
+ BOOST_ASSERT(b_.size() == 1);
+
+ // char_('x', 'y')
+ return fragments.new_rule(qi::char_(a_[0], b_[0]));
+ }
+
+ utree eval(scope const& env) const
+ {
+ if (b.empty())
+ return eval(a(env));
+ else
+ return eval(a(env), b(env));
+ }
+ };
+
+ template <typename Fragments>
+ struct unary_char_composite
+ : composite<unary_char_composite<Fragments> >
+ {
+ Fragments& fragments;
+ unary_char_composite(Fragments& fragments)
+ : fragments(fragments) {}
+
+ function compose(actor_list const& elements) const
+ {
+ typedef char_function<Fragments> function_type;
+ actor_list::const_iterator i = elements.begin();
+
+ function empty;
+ function const& a = *i++;
+ function const& b = (i == elements.end())? empty : *i;
+ return function(function_type(fragments, a, b));
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Build our scheme compiler environment.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Fragments>
+ void build_environment(Fragments& fragments, environment& env)
     {
         build_basic_environment(env);
+
         env.define("qi:space",
             make_primitive_parser_composite(fragments, qi::space), 0, true);
+
         env.define("qi:alpha",
             make_primitive_parser_composite(fragments, qi::alpha), 0, true);
+
         env.define("qi:int_",
             make_primitive_parser_composite(fragments, qi::int_), 0, true);
+
+ env.define("qi:char_",
+ unary_char_composite<Fragments>(fragments), 1, false);
     }
-}
+}}
 
 ///////////////////////////////////////////////////////////////////////////////
 // Main program
 ///////////////////////////////////////////////////////////////////////////////
 int main()
 {
+ using scheme::utree;
     using scheme::interpreter;
     using scheme::environment;
- using scheme::build_qi_environment;
- using scheme::rule_fragments;
- using scheme::rule_type;
- using scheme::utree;
+ using scheme::qi::build_environment;
+ using scheme::qi::rule_fragments;
+ using scheme::qi::rule_type;
+ using spirit_test::test;
 
     environment env;
     rule_fragments<rule_type> fragments;
- build_qi_environment(fragments, env);
+ build_environment(fragments, env);
+
+ scheme::qi::skipper_type space = boost::spirit::qi::space;
 
     {
- utree src = "(define foo 123)";
+ utree src =
+ "(define r (qi:char_ \"x\"))"
+ "(define r2 (qi:int_))";
         interpreter parser(src, "parse.scm", &env);
- std::cout << parser["qi:int_"]() << std::endl;
+ //~ std::cout << parser["r"]() << std::endl;
+ //~ std::cout << parser["r2"]() << std::endl;
+
+ BOOST_TEST(test("x", fragments.get_rule(parser["r"]()), space));
+ BOOST_TEST(!test("y", fragments.get_rule(parser["r"]()), space));
+
+
     }
 
     return boost::report_errors();

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-25 22:02:48 EDT (Sun, 25 Apr 2010)
@@ -20,9 +20,17 @@
     using scheme::interpreter;
     using scheme::utree;
 
- utree src = "(define (factorial n) (if (<= n 0) 1 (* n (factorial (- n 1)))))";
- scheme::interpreter program(src);
- BOOST_TEST(program["factorial"](10) == 3628800);
+ {
+ utree src = "(define n 123)";
+ scheme::interpreter program(src);
+ BOOST_TEST(program["n"]() == 123);
+ }
+
+ {
+ utree src = "(define (factorial n) (if (<= n 0) 1 (* n (factorial (- n 1)))))";
+ scheme::interpreter program(src);
+ BOOST_TEST(program["factorial"](10) == 3628800);
+ }
 
     return boost::report_errors();
 }


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