$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r61348 - in trunk/libs/spirit/example/scheme: input scheme support test/scheme utree utree/detail
From: joel_at_[hidden]
Date: 2010-04-18 01:24:47
Author: djowel
Date: 2010-04-18 01:24:45 EDT (Sun, 18 Apr 2010)
New Revision: 61348
URL: http://svn.boost.org/trac/boost/changeset/61348
Log:
compiler error handling/reporting
Text files modified: 
   trunk/libs/spirit/example/scheme/input/error_handler.hpp        |    18 ---                                     
   trunk/libs/spirit/example/scheme/input/sexpr.hpp                |    30 ++++++                                  
   trunk/libs/spirit/example/scheme/scheme/compiler.hpp            |   172 ++++++++++++++++++++++++++++----------- 
   trunk/libs/spirit/example/scheme/support/line_pos_iterator.hpp  |     2                                         
   trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp   |     2                                         
   trunk/libs/spirit/example/scheme/utree/detail/utree_detail1.hpp |     1                                         
   trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp |    14 +++                                     
   trunk/libs/spirit/example/scheme/utree/operators.hpp            |    18 ++--                                    
   trunk/libs/spirit/example/scheme/utree/utree.hpp                |     5                                         
   9 files changed, 180 insertions(+), 82 deletions(-)
Modified: trunk/libs/spirit/example/scheme/input/error_handler.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/input/error_handler.hpp	(original)
+++ trunk/libs/spirit/example/scheme/input/error_handler.hpp	2010-04-18 01:24:45 EDT (Sun, 18 Apr 2010)
@@ -36,23 +36,9 @@
                 std::cerr << source_file;
 
             if (line != -1)
-            {
-                if (source_file != "")
-                    std::cerr << '(' << line << ')';
-                else
-                    std::cerr << '(' << line << ')';
-            }
+                std::cerr << '(' << line << ')';
 
-            std::cerr << " : Error! Expecting "  << what;
-            //~ if (line != -1)
-            //~ {
-                //~ std::size_t col = get_column(first, err_pos, 4);
-                //~ std::cerr << " near column " << col << std::endl;
-            //~ }
-            //~ else
-            //~ {
-                std::cerr << std::endl;
-            //~ }
+            std::cerr << " : Error! Expecting "  << what << std::endl;
         }
     };
 }}
Modified: trunk/libs/spirit/example/scheme/input/sexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/input/sexpr.hpp	(original)
+++ trunk/libs/spirit/example/scheme/input/sexpr.hpp	2010-04-18 01:24:45 EDT (Sun, 18 Apr 2010)
@@ -40,10 +40,15 @@
     using boost::spirit::qi::lexeme;
     using boost::spirit::qi::on_error;
     using boost::spirit::qi::fail;
+    using boost::spirit::qi::_val;
     using boost::spirit::qi::_1;
     using boost::spirit::qi::_2;
     using boost::spirit::qi::_3;
     using boost::spirit::qi::_4;
+    using boost::spirit::qi::locals;
+    using boost::spirit::qi::raw;
+    using boost::spirit::qi::eps;
+    using boost::spirit::qi::omit;
     using boost::spirit::info;
 
     typedef boost::uint32_t uchar; // a unicode code point
@@ -62,6 +67,23 @@
         rule<Iterator> start;
     };
 
+    struct save_line_pos_
+    {
+        template <typename Utree, typename Range>
+        struct result { typedef void type; };
+
+        template <typename Range>
+        void operator()(utree& ast, Range const& rng) const
+        {
+            int n = get_line(rng.begin());
+            BOOST_ASSERT(n <= std::numeric_limits<short>::max());
+            ast.tag(n);
+        }
+    };
+
+    boost::phoenix::function<save_line_pos_> const
+        save_line_pos = save_line_pos_();
+
     template <typename Iterator,
         typename ErrorHandler = input::error_handler<Iterator> >
     struct sexpr : grammar<Iterator, sexpr_white_space<Iterator>, utree()>
@@ -75,7 +97,11 @@
             start   = element.alias();
             element = atom | list;
 
-            list    = '(' > *element > ')';
+            list    %= '('
+                    > omit[raw[eps]         [save_line_pos(_val, _1)]]
+                    > *element
+                    > ')'
+                    ;
 
             atom    = strict_double
                     | integer
@@ -106,7 +132,7 @@
         }
 
         rule<Iterator, sexpr_white_space<Iterator>, utree()>
-            start, list, element;
+            start, element, list;
         rule<Iterator, int()> integer;
         rule<Iterator, utree()> atom;
         rule<Iterator, utf8_symbol()> symbol;
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-18 01:24:45 EDT (Sun, 18 Apr 2010)
@@ -9,8 +9,9 @@
 
 #include <vector>
 #include <map>
-#include <boost/bind.hpp>
+#include <exception>
 
+#include <boost/bind.hpp>
 #include <scheme/intrinsics.hpp>
 #include <scheme/interpreter.hpp>
 #include <input/parse_sexpr.hpp>
@@ -18,6 +19,35 @@
 namespace scheme
 {
 ///////////////////////////////////////////////////////////////////////////////
+//  Exceptions
+///////////////////////////////////////////////////////////////////////////////
+    struct scheme_exception : std::exception {};
+
+    struct identifier_not_found : scheme_exception
+    {
+        virtual const char* what() const throw()
+        {
+            return "scheme: Identifier not found";
+        }
+    };
+
+    struct duplicate_identifier : scheme_exception
+    {
+        virtual const char* what() const throw()
+        {
+            return "scheme: Duplicate identifier";
+        }
+    };
+
+    struct unknown_expression : scheme_exception
+    {
+        virtual const char* what() const throw()
+        {
+            return "scheme: Unknown_expression";
+        }
+    };
+
+///////////////////////////////////////////////////////////////////////////////
 //  The environment
 ///////////////////////////////////////////////////////////////////////////////
     typedef boost::function<function(actor_list const&)> compiled_function;
@@ -32,8 +62,8 @@
         template <typename Function>
         void define(std::string const& name, Function const& f)
         {
-            // $$$ use exceptions here? $$$
-            BOOST_ASSERT(definitions.find(name) == definitions.end());
+            if (definitions.find(name) != definitions.end())
+                throw duplicate_identifier();
             definitions[name] = compiled_function(f);
         }
 
@@ -60,7 +90,11 @@
 //  The compiler
 ///////////////////////////////////////////////////////////////////////////////
     function compile(
-        utree const& ast, environment& env, actor_list& fragments);
+        utree const& ast,
+        environment& env,
+        actor_list& fragments,
+        int parent_line,
+        std::string const& source_file = "");
 
     struct external_function : composite<external_function>
     {
@@ -82,9 +116,16 @@
         typedef function result_type;
         environment& env;
         actor_list& fragments;
+        int line;
+        std::string source_file;
 
-        compiler(environment& env, actor_list& fragments)
-          : env(env), fragments(fragments)
+        compiler(
+            environment& env,
+            actor_list& fragments,
+            int line,
+            std::string const& source_file = "")
+          : env(env), fragments(fragments),
+            line(line), source_file(source_file)
         {
         }
 
@@ -107,8 +148,7 @@
                 actor_list flist;
                 return (*mf)(flist);
             }
-            // $$$ throw? $$$
-            BOOST_ASSERT(false);
+            throw identifier_not_found();
             return function();
         }
 
@@ -119,7 +159,7 @@
             environment local_env(&this->env);
             for (std::size_t i = 0; i < args.size(); ++i)
                 local_env.define(args[i], boost::bind(arg, i));
-            return compile(body, local_env, fragments);
+            return compile(body, local_env, fragments, line, source_file);
         }
 
         function define_function(
@@ -137,55 +177,71 @@
         template <typename Iterator>
         function operator()(boost::iterator_range<Iterator> const& range) const
         {
-            std::string name(get_symbol(*range.begin()));
-
-            if (name == "define")
+            try
             {
-                std::string fname;
-                std::vector<std::string> args;
+                std::string name(get_symbol(*range.begin()));
 
-                Iterator i = range.begin(); ++i;
-                if (i->which() == utree_type::list_type)
+                if (name == "define")
                 {
-                    // (define (f x) ...body...)
-                    utree const& decl = *i++;
-                    Iterator di = decl.begin();
-                    fname = get_symbol(*di++);
-                    while (di != decl.end())
-                        args.push_back(get_symbol(*di++));
+                    std::string fname;
+                    std::vector<std::string> args;
+
+                    Iterator i = range.begin(); ++i;
+                    if (i->which() == utree_type::list_type)
+                    {
+                        // (define (f x) ...body...)
+                        utree const& decl = *i++;
+                        Iterator di = decl.begin();
+                        fname = get_symbol(*di++);
+                        while (di != decl.end())
+                            args.push_back(get_symbol(*di++));
+                    }
+                    else
+                    {
+                        // (define f ...body...)
+                        fname = get_symbol(*i++);
+                    }
+
+                    return define_function(fname, args, *i);
                 }
-                else
+
+                if (name == "lambda")
                 {
-                    // (define f ...body...)
-                    fname = get_symbol(*i++);
+                    // (lambda (x) ...body...)
+                    Iterator i = range.begin(); ++i;
+                    utree const& arg_names = *i++;
+                    Iterator ai = arg_names.begin();
+                    std::vector<std::string> args;
+                    while (ai != arg_names.end())
+                        args.push_back(get_symbol(*ai++));
+                    return make_lambda(args, *i);
                 }
 
-                return define_function(fname, args, *i);
-            }
+                if (compiled_function* mf = env.find(name))
+                {
+                    actor_list flist;
+                    Iterator i = range.begin(); ++i;
+                    for (; i != range.end(); ++i)
+                        flist.push_back(
+                            compile(*i, env, fragments, line, source_file));
+                    return (*mf)(flist);
+                }
 
-            if (name == "lambda")
-            {
-                // (lambda (x) ...body...)
-                Iterator i = range.begin(); ++i;
-                utree const& arg_names = *i++;
-                Iterator ai = arg_names.begin();
-                std::vector<std::string> args;
-                while (ai != arg_names.end())
-                    args.push_back(get_symbol(*ai++));
-                return make_lambda(args, *i);
+                throw unknown_expression();
             }
 
-            if (compiled_function* mf = env.find(name))
+            catch (scheme_exception const& x)
             {
-                actor_list flist;
-                Iterator i = range.begin(); ++i;
-                for (; i != range.end(); ++i)
-                    flist.push_back(compile(*i, env, fragments));
-                return (*mf)(flist);
+                if (source_file != "")
+                    std::cerr << source_file;
+
+                if (line != -1)
+                    std::cerr << '(' << line << ')';
+
+                std::cerr << " : Error! "  << x.what() << std::endl;
             }
 
-            BOOST_ASSERT(false);
-            return function(); // $$$ implement me $$$
+            return function();
         }
 
         static std::string get_symbol(utree const& s)
@@ -196,20 +252,31 @@
     };
 
     inline function compile(
-        utree const& ast, environment& env, actor_list& fragments)
+        utree const& ast,
+        environment& env,
+        actor_list& fragments,
+        int parent_line,
+        std::string const& source_file)
     {
-        return utree::visit(ast, compiler(env, fragments));
+        int line = (ast.which() == utree_type::list_type)
+            ? ast.tag() : parent_line;
+        return utree::visit(ast,
+            compiler(env, fragments, line, source_file));
     }
 
     void compile_all(
         utree const& ast,
         environment& env,
         actor_list& results,
-        actor_list& fragments)
+        actor_list& fragments,
+        std::string const& source_file = "")
     {
+        int line = (ast.which() == utree_type::list_type)
+            ? ast.tag() : 1;
         BOOST_FOREACH(utree const& program, ast)
         {
-            scheme::function f = compile(program, env, fragments);
+            scheme::function
+                f = compile(program, env, fragments, line, source_file);
             results.push_back(f);
         }
     }
@@ -230,14 +297,17 @@
     struct interpreter : actor<interpreter>
     {
         template <typename Source>
-        interpreter(Source& in, environment* outer = 0)
+        interpreter(
+            Source& in,
+            std::string const& source_file = "",
+            environment* outer = 0)
         {
             if (outer == 0)
                 build_basic_environment(env);
 
             if (input::parse_sexpr_list(in, program))
             {
-                compile_all(program, env, flist, fragments);
+                compile_all(program, env, flist, fragments, source_file);
             }
             else
             {
Modified: trunk/libs/spirit/example/scheme/support/line_pos_iterator.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/support/line_pos_iterator.hpp	(original)
+++ trunk/libs/spirit/example/scheme/support/line_pos_iterator.hpp	2010-04-18 01:24:45 EDT (Sun, 18 Apr 2010)
@@ -17,7 +17,7 @@
     // adapter only stores the current line number, nothing else. Unlike
     // spirit classic's position_iterator, it does not store the column
     // number and does not need an end iterator. The current column can be
-    // computed, if needed. Some utilities line oriented are provided
+    // computed, if needed. Some line oriented utilities are provided
     // including computation of the current column.
     ///////////////////////////////////////////////////////////////////////////
     template <typename Iterator>
Modified: trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp	(original)
+++ trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.cpp	2010-04-18 01:24:45 EDT (Sun, 18 Apr 2010)
@@ -65,7 +65,7 @@
     scheme::build_basic_environment(env);
     scheme::actor_list fragments;
     scheme::actor_list flist;
-    compile_all(program, env, flist, fragments);
+    compile_all(program, env, flist, fragments, filename);
 
     scheme::actor_list::iterator i = flist.begin();
 
Modified: trunk/libs/spirit/example/scheme/test/scheme/scheme_test1.scm
==============================================================================
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-18 01:24:45 EDT (Sun, 18 Apr 2010)
@@ -53,6 +53,7 @@
         node* first;
         node* last;
         std::size_t size;
+        short tag;
     };
 
     ///////////////////////////////////////////////////////////////////////////
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-18 01:24:45 EDT (Sun, 18 Apr 2010)
@@ -258,6 +258,7 @@
         first = last = 0;
         size = 0;
         node* p = other.first;
+        tag = other.tag;
         while (p != 0)
         {
             push_back(p->val);
@@ -1069,10 +1070,21 @@
     {
         return (get_type() == type::reference_type) ? *p : *this;
     }
+
+    inline short utree::tag() const
+    {
+        BOOST_ASSERT(get_type() == type::list_type);
+        return l.tag;
+    }
+
+    inline void utree::tag(short tag)
+    {
+        ensure_list_type();
+        l.tag = tag;
+    }
 }
 
 #if defined(BOOST_MSVC)
 # pragma warning(pop)
 #endif
-
 #endif
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-18 01:24:45 EDT (Sun, 18 Apr 2010)
@@ -150,38 +150,38 @@
 //     struct utree_print
 //     {
 //         typedef void result_type;
-// 
+//
 //         std::ostream& out;
 //         utree_print(std::ostream& out) : out(out) {}
-// 
+//
 //         void operator()(scheme::nil) const
 //         {
 //             out << "nil";
 //         }
-// 
+//
 //         template <typename T>
 //         void operator()(T val) const
 //         {
 //             out << val;
 //         }
-// 
+//
 //         void operator()(bool b) const
 //         {
 //             out << (b ? "true" : "false");
 //         }
-// 
+//
 //         void operator()(binary_range const& b) const
 //         {
 //             out << "b";
 //             out.width(2);
 //             out.fill('0');
-// 
+//
 //             typedef binary_range::const_iterator iterator;
 //             for (iterator i = b.begin(); i != b.end(); ++i)
 //                 out << std::hex << int((unsigned char)*i);
 //             out << std::dec;
 //         }
-// 
+//
 //         void operator()(utf8_string_range const& str) const
 //         {
 //             typedef utf8_string_range::const_iterator iterator;
@@ -191,7 +191,7 @@
 //                 out << *i;
 //             out << '"';
 //         }
-// 
+//
 //         void operator()(utf8_symbol_range const& str) const
 //         {
 //             typedef utf8_symbol_range::const_iterator iterator;
@@ -199,7 +199,7 @@
 //             for (; i != str.end(); ++i)
 //                 out << *i;
 //         }
-// 
+//
 //         template <typename Iterator>
 //         void operator()(boost::iterator_range<Iterator> const& range) 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-18 01:24:45 EDT (Sun, 18 Apr 2010)
@@ -153,7 +153,7 @@
         typedef utree value_type;
         typedef detail::list::node_iterator<utree> iterator;
         typedef detail::list::node_iterator<utree const> const_iterator;
-        typedef detail::list::node_iterator<boost::reference_wrapper<utree> > 
+        typedef detail::list::node_iterator<boost::reference_wrapper<utree> >
             ref_iterator;
         typedef utree& reference;
         typedef utree const& const_reference;
@@ -272,6 +272,9 @@
         utree& deref();
         utree const& deref() const;
 
+        short tag() const;
+        void tag(short tag);
+
     private:
 
         typedef utree_type type;