Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r73376 - trunk/libs/spirit/example/qi/compiler_tutorial/conjure3
From: joel_at_[hidden]
Date: 2011-07-26 09:34:52


Author: djowel
Date: 2011-07-26 09:34:51 EDT (Tue, 26 Jul 2011)
New Revision: 73376
URL: http://svn.boost.org/trac/boost/changeset/73376

Log:
Literals
Text files modified:
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/annotation.hpp | 67 +++++++++++++++++++++++++++++++--------
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/ast.hpp | 24 +++++++++++++-
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/compiler.cpp | 12 +++++++
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/compiler.hpp | 1
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/expression.hpp | 1
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/expression_def.hpp | 8 +++-
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/ids.hpp | 5 --
   7 files changed, 95 insertions(+), 23 deletions(-)

Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/annotation.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/annotation.hpp (original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/annotation.hpp 2011-07-26 09:34:51 EDT (Tue, 26 Jul 2011)
@@ -20,45 +20,82 @@
     // for the purpose of subsequent semantic error handling when the
     // program is being compiled.
     ///////////////////////////////////////////////////////////////////////////////
- template <typename Iterator>
- struct annotation
- {
- template <typename, typename>
- struct result { typedef void type; };
-
- std::vector<Iterator>& iters;
- annotation(std::vector<Iterator>& iters)
- : iters(iters) {}
-
- struct set_id
+ struct set_annotation_id
         {
             typedef void result_type;
 
             int id;
- set_id(int id) : id(id) {}
+ set_annotation_id(int id) : id(id) {}
 
             void operator()(ast::function_call& x) const
             {
                 x.function_name.id = id;
             }
 
- void operator()(ast::identifier& x) const
+ template <typename T>
+ void dispatch(T& x, boost::mpl::true_) const
             {
                 x.id = id;
             }
 
             template <typename T>
+ void dispatch(T& x, boost::mpl::false_) const
+ {
+ // no-op
+ }
+
+ template <typename T>
             void operator()(T& x) const
             {
- // no-op
+ typename boost::is_base_of<ast::tagged, T> is_tagged;
+ dispatch(x, is_tagged);
             }
         };
 
+ struct get_annotation_id
+ {
+ typedef int result_type;
+
+ int operator()(ast::function_call& x) const
+ {
+ return x.function_name.id;
+ }
+
+ template <typename T>
+ int dispatch(T& x, boost::mpl::true_) const
+ {
+ return x.id;
+ }
+
+ template <typename T>
+ int dispatch(T& x, boost::mpl::false_) const
+ {
+ return -1;
+ }
+
+ template <typename T>
+ int operator()(T& x) const
+ {
+ typename boost::is_base_of<ast::tagged, T> is_tagged;
+ return dispatch(x, is_tagged);
+ }
+ };
+
+ template <typename Iterator>
+ struct annotation
+ {
+ template <typename, typename>
+ struct result { typedef void type; };
+
+ std::vector<Iterator>& iters;
+ annotation(std::vector<Iterator>& iters)
+ : iters(iters) {}
+
         void operator()(ast::operand& ast, Iterator pos) const
         {
             int id = iters.size();
             iters.push_back(pos);
- boost::apply_visitor(set_id(id), ast);
+ boost::apply_visitor(set_annotation_id(id), ast);
         }
 
         void operator()(ast::assignment& ast, Iterator pos) const

Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/ast.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/ast.hpp (original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/ast.hpp 2011-07-26 09:34:51 EDT (Tue, 26 Jul 2011)
@@ -12,6 +12,7 @@
 #include <boost/variant/recursive_variant.hpp>
 #include <boost/fusion/include/adapt_struct.hpp>
 #include <boost/fusion/include/io.hpp>
+#include <boost/spirit/include/support_attributes.hpp>
 #include <boost/optional.hpp>
 #include <list>
 
@@ -40,10 +41,29 @@
         std::string name;
     };
 
+ struct literal : tagged
+ {
+ // tell spirit that this is an adapted variant
+ struct adapted_variant;
+
     typedef boost::variant<
             nil
           , bool
- , unsigned int
+ , unsigned int>
+ variant_type;
+
+ typedef variant_type::types types;
+
+ literal() : val() {}
+ literal(bool val) : val(val) {}
+ literal(unsigned int val) : val(val) {}
+
+ variant_type val;
+ };
+
+ typedef boost::variant<
+ nil
+ , literal
           , identifier
           , boost::recursive_wrapper<unary>
           , boost::recursive_wrapper<function_call>
@@ -51,7 +71,7 @@
>
     operand;
 
- struct unary
+ struct unary : tagged
     {
         token::type operator_;
         operand operand_;

Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/compiler.cpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/compiler.cpp (original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/compiler.cpp 2011-07-26 09:34:51 EDT (Tue, 26 Jul 2011)
@@ -6,6 +6,7 @@
 =============================================================================*/
 #include "config.hpp"
 #include "compiler.hpp"
+#include "annotation.hpp"
 #include "vm.hpp"
 
 #include <boost/foreach.hpp>
@@ -47,6 +48,11 @@
         return llvm::ConstantInt::get(context(), llvm::APInt(1, x));
     }
 
+ llvm::Value* compiler::operator()(ast::literal const& x)
+ {
+ return boost::apply_visitor(*this, x.val);
+ }
+
     llvm::Value* compiler::operator()(ast::identifier const& x)
     {
         // Look this variable up in the function.
@@ -166,6 +172,12 @@
         return precedence[op & 0xFF];
     }
 
+ inline bool is_left_assoc(token::type op)
+ {
+ // only the assignment operators are right to left
+ return (op & token::op_assign) == 0;
+ }
+
     llvm::Value* compiler::compile_binary_expression(
         llvm::Value* lhs, llvm::Value* rhs, token::type op)
     {

Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/compiler.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/compiler.hpp (original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/compiler.hpp 2011-07-26 09:34:51 EDT (Tue, 26 Jul 2011)
@@ -58,6 +58,7 @@
         llvm::Value* operator()(ast::nil) { BOOST_ASSERT(0); return 0; }
         llvm::Value* operator()(unsigned int x);
         llvm::Value* operator()(bool x);
+ llvm::Value* operator()(ast::literal const& x);
         llvm::Value* operator()(ast::identifier const& x);
         llvm::Value* operator()(ast::unary const& x);
         llvm::Value* operator()(ast::function_call const& x);

Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/expression.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/expression.hpp (original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/expression.hpp 2011-07-26 09:34:51 EDT (Tue, 26 Jul 2011)
@@ -50,6 +50,7 @@
         qi::rule<Iterator, ast::function_call()> function_call;
         qi::rule<Iterator, std::list<ast::expression>()> argument_list;
         qi::rule<Iterator, std::string()> identifier;
+ qi::rule<Iterator, ast::literal()> literal;
     };
 }}
 

Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/expression_def.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/expression_def.hpp (original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/expression_def.hpp 2011-07-26 09:34:51 EDT (Tue, 26 Jul 2011)
@@ -50,13 +50,17 @@
             ;
 
         primary_expr =
- lexer.lit_uint
+ literal
             | function_call
             | identifier
- | lexer.true_or_false
             | '(' > expr > ')'
             ;
 
+ literal =
+ lexer.lit_uint
+ | lexer.true_or_false
+ ;
+
         function_call =
                 (identifier >> '(')
> argument_list

Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/ids.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/ids.hpp (original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/ids.hpp 2011-07-26 09:34:51 EDT (Tue, 26 Jul 2011)
@@ -67,10 +67,7 @@
     template <int type, int op>
     struct make_op
     {
- static int const value =
- + type
- + op
- ;
+ static int const value = type + op;
     };
 
     template <op::type op>


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