Boost logo

Boost-Commit :

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;


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