$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r61573 - in trunk/libs/spirit/example/scheme: scheme test/qi
From: joel_at_[hidden]
Date: 2010-04-26 07:35:52
Author: djowel
Date: 2010-04-26 07:35:51 EDT (Mon, 26 Apr 2010)
New Revision: 61573
URL: http://svn.boost.org/trac/boost/changeset/61573
Log:
lists of ints grammar almost working
Text files modified: 
   trunk/libs/spirit/example/scheme/scheme/compiler.hpp        |     3                                         
   trunk/libs/spirit/example/scheme/test/qi/qi_interpreter.cpp |   129 +++++++++++++++++++++++++++++++++++++++ 
   2 files changed, 130 insertions(+), 2 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-26 07:35:51 EDT (Mon, 26 Apr 2010)
@@ -401,7 +401,8 @@
                     fname = get_symbol(*i++);
 
                     // (define f (lambda (x) ...body...))
-                    if (i->which() == utree_type::list_type
+                    if (i != range.end()
+                        && i->which() == utree_type::list_type
                         && get_symbol((*i)[0]) == "lambda")
                     {
                         utree const& arg_names = (*i)[1];
Modified: trunk/libs/spirit/example/scheme/test/qi/qi_interpreter.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/qi/qi_interpreter.cpp	(original)
+++ trunk/libs/spirit/example/scheme/test/qi/qi_interpreter.cpp	2010-04-26 07:35:51 EDT (Mon, 26 Apr 2010)
@@ -12,6 +12,9 @@
 #include <scheme/compiler.hpp>
 #include <utree/io.hpp>
 #include <boost/spirit/include/qi.hpp>
+
+#include <iostream>
+#include <fstream>
 #include <map>
 
 #include "../../../../test/qi/test.hpp"
@@ -372,6 +375,109 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
+    // Handles the compilation of alternatives a | b
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Fragments>
+    struct alternative_function : actor<alternative_function<Fragments> >
+    {
+        Fragments& fragments;
+        actor_list elements;
+        alternative_function(
+            Fragments& fragments, actor_list const& elements)
+          : elements(elements), fragments(fragments)
+        {
+        }
+
+        utree eval(utree const& a, utree const& b) const
+        {
+            // a | b
+            return fragments.new_rule(
+                fragments[a] | fragments[b]);
+        }
+
+        utree eval(utree const& a, utree const& b, utree const& c) const
+        {
+            // a | b | c
+            return fragments.new_rule(
+                fragments[a] | fragments[b] | fragments[c]);
+        }
+
+        utree eval(utree const& a, utree const& b, utree const& c,
+            utree const& d) const
+        {
+            // a | b | c | d
+            return fragments.new_rule(
+                fragments[a] | fragments[b] | fragments[c] |
+                fragments[d]);
+        }
+
+        utree eval(utree const& a, utree const& b, utree const& c,
+            utree const& d, utree const& e) const
+        {
+            // a | b | c | d | e
+            return fragments.new_rule(
+                fragments[a] | fragments[b] | fragments[c] |
+                fragments[d] | fragments[e]);
+        }
+
+        utree eval(scope const& env) const
+        {
+            actor_list::const_iterator i = elements.begin();
+            switch (elements.size())
+            {
+                case 2:
+                {
+                    function const& a = *i++;
+                    function const& b = *i;
+                    return eval(a(env), b(env));
+                }
+                case 3:
+                {
+                    function const& a = *i++;
+                    function const& b = *i++;
+                    function const& c = *i;
+                    return eval(a(env), b(env), c(env));
+                }
+                case 4:
+                {
+                    function const& a = *i++;
+                    function const& b = *i++;
+                    function const& c = *i++;
+                    function const& d = *i;
+                    return eval(a(env), b(env), c(env), d(env));
+                }
+                case 5:
+                {
+                    function const& a = *i++;
+                    function const& b = *i++;
+                    function const& c = *i++;
+                    function const& d = *i++;
+                    function const& e = *i;
+                    return eval(a(env), b(env), c(env), d(env), e(env));
+                }
+
+                // $$$ Use Boost PP using SCHEME_QI_COMPILER_LIMIT $$$
+            }
+            return utree();
+        }
+    };
+
+    template <typename Fragments>
+    struct alternative_composite
+      : composite<alternative_composite<Fragments> >
+    {
+        Fragments& fragments;
+        alternative_composite(Fragments& fragments)
+          : fragments(fragments) {}
+
+        function compose(actor_list const& elements) const
+        {
+            typedef alternative_function<Fragments> function_type;
+            return function(function_type(fragments, elements));
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
     // Build our scheme compiler environment.
     ///////////////////////////////////////////////////////////////////////////
     template <typename Fragments>
@@ -399,6 +505,9 @@
 
         env.define("qi:>>",
             sequence_composite<Fragments>(fragments), 2, false);
+
+        env.define("qi:|",
+            alternative_composite<Fragments>(fragments), 2, false);
     }
 }}
 
@@ -449,7 +558,25 @@
     }
 
     {
-        //~ utree src =
+        char const* filename = filename = "calc.scm";
+        std::ifstream in(filename, std::ios_base::in);
+
+        BOOST_TEST(in);
+
+        // Ignore the BOM marking the beginning of a UTF-8 file in Windows
+        char c = in.peek();
+        if (c == '\xef')
+        {
+            char s[3];
+            in >> s[0] >> s[1] >> s[2];
+            s[3] = '\0';
+            BOOST_TEST(s != std::string("\xef\xbb\xbf"));
+        }
+
+        interpreter parser(in, filename, &env);
+
+        BOOST_TEST(!test("1 + 1",
+            fragments[parser["expression"]()], space));
 
     }