$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r73565 - in trunk/libs/spirit/example/qi/compiler_tutorial: conjure1 conjure2 conjure3 conjure_samples mini_c
From: joel_at_[hidden]
Date: 2011-08-05 23:14:50
Author: djowel
Date: 2011-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
New Revision: 73565
URL: http://svn.boost.org/trac/boost/changeset/73565
Log:
conjure3 assign-ops + bug fixes for all
Added:
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure_samples/operators.cnj   (contents, props changed)
Text files modified: 
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure1/annotation.hpp    |     7 +++++                                   
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure1/statement_def.hpp |     5 ++                                      
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure2/annotation.hpp    |     7 +++++                                   
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure2/statement_def.hpp |     5 ++                                      
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/annotation.hpp    |     7 +++++                                   
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/compiler.cpp      |    56 ++++++++++++++++++++++++++++++++++++++- 
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/lexer_def.hpp     |    40 +++++++++++++++++----------             
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/statement_def.hpp |     7 ++++                                    
   trunk/libs/spirit/example/qi/compiler_tutorial/conjure_samples/error.cnj  |     2                                         
   trunk/libs/spirit/example/qi/compiler_tutorial/mini_c/annotation.hpp      |     7 +++++                                   
   trunk/libs/spirit/example/qi/compiler_tutorial/mini_c/statement_def.hpp   |     5 ++                                      
   11 files changed, 126 insertions(+), 22 deletions(-)
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure1/annotation.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure1/annotation.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure1/annotation.hpp	2011-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
@@ -61,6 +61,13 @@
             boost::apply_visitor(set_id(id), ast);
         }
 
+        void operator()(ast::variable_declaration& ast, Iterator pos) const
+        {
+            int id = iters.size();
+            iters.push_back(pos);
+            ast.lhs.id = id;
+        }
+
         void operator()(ast::assignment& ast, Iterator pos) const
         {
             int id = iters.size();
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure1/statement_def.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure1/statement_def.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure1/statement_def.hpp	2011-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
@@ -114,7 +114,10 @@
             error_handler_function(error_handler)(
                 "Error! Expecting ", _4, _3));
 
-        // Annotation: on success in assignment, call annotation.
+        // Annotation: on success in variable_declaration,
+        // assignment and return_statement, call annotation.
+        on_success(variable_declaration,
+            annotation_function(error_handler.iters)(_val, _1));
         on_success(assignment,
             annotation_function(error_handler.iters)(_val, _1));
         on_success(return_statement,
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure2/annotation.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure2/annotation.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure2/annotation.hpp	2011-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
@@ -61,6 +61,13 @@
             boost::apply_visitor(set_id(id), ast);
         }
 
+        void operator()(ast::variable_declaration& ast, Iterator pos) const
+        {
+            int id = iters.size();
+            iters.push_back(pos);
+            ast.lhs.id = id;
+        }
+
         void operator()(ast::assignment& ast, Iterator pos) const
         {
             int id = iters.size();
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure2/statement_def.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure2/statement_def.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure2/statement_def.hpp	2011-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
@@ -110,7 +110,10 @@
             error_handler_function(error_handler)(
                 "Error! Expecting ", _4, _3));
 
-        // Annotation: on success in assignment, call annotation.
+        // Annotation: on success in variable_declaration,
+        // assignment and return_statement, call annotation.
+        on_success(variable_declaration,
+            annotation_function(error_handler.iters)(_val, _1));
         on_success(assignment,
             annotation_function(error_handler.iters)(_val, _1));
         on_success(return_statement,
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-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
@@ -98,6 +98,13 @@
             boost::apply_visitor(set_annotation_id(id), ast);
         }
 
+        void operator()(ast::variable_declaration& ast, Iterator pos) const
+        {
+            int id = iters.size();
+            iters.push_back(pos);
+            ast.lhs.id = id;
+        }
+
         void operator()(ast::assignment& ast, Iterator pos) const
         {
             int id = iters.size();
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-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
@@ -246,8 +246,60 @@
         if (rhs == 0)
             return 0;
 
-        builder.CreateStore(rhs, lhs);
-        return rhs;
+        if (x.operator_ == token_ids::assign)
+        {
+            builder.CreateStore(rhs, lhs);
+            return rhs;
+        }
+
+        llvm::Value* result = builder.CreateLoad(lhs, x.lhs.name.c_str());
+        switch (x.operator_)
+        {
+            case token_ids::plus_assign:
+                result = builder.CreateAdd(result, rhs, "addtmp");
+                break;
+
+            case token_ids::minus_assign:
+                result = builder.CreateSub(result, rhs, "subtmp");
+                break;
+
+            case token_ids::times_assign:
+                result = builder.CreateMul(result, rhs, "multmp");
+                break;
+
+            case token_ids::divide_assign:
+                result = builder.CreateSDiv(result, rhs, "divtmp");
+                break;
+
+            case token_ids::mod_assign:
+                result = builder.CreateSRem(result, rhs, "modtmp");
+                break;
+
+            case token_ids::bit_and_assign:
+                result = builder.CreateAnd(result, rhs, "andtmp");
+                break;
+
+            case token_ids::bit_xor_assign:
+                result = builder.CreateXor(result, rhs, "xortmp");
+                break;
+
+            case token_ids::bit_or_assign:
+                result = builder.CreateOr(result, rhs, "ortmp");
+                break;
+
+            case token_ids::shift_left_assign:
+                result = builder.CreateShl(result, rhs, "shltmp");
+                break;
+
+            case token_ids::shift_right_assign:
+                result = builder.CreateLShr(result, rhs, "shrtmp");
+                break;
+
+            default: BOOST_ASSERT(0); return 0;
+        }
+
+        builder.CreateStore(result, lhs);
+        return result;
     }
 
     //  Create an alloca instruction in the entry block of
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/lexer_def.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/lexer_def.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/lexer_def.hpp	2011-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
@@ -28,27 +28,37 @@
                 ("else")
                 ("while")
                 ("return")
-                ("=", token_ids::assign)
-                ("\\|\\|", token_ids::logical_or)
-                ("&&", token_ids::logical_and)
-                ("==", token_ids::equal)
-                ("!=", token_ids::not_equal)
-                ("<", token_ids::less)
-                ("<=", token_ids::less_equal)
-                (">", token_ids::greater)
-                (">=", token_ids::greater_equal)
-                ("\\+", token_ids::plus)
-                ("\\-", token_ids::minus)
-                ("\\*", token_ids::times)
-                ("\\/", token_ids::divide)
-                ("!", token_ids::not_)
+                ("=",       token_ids::assign)
+                ("\\+=",    token_ids::plus_assign)
+                ("\\-=",    token_ids::minus_assign)
+                ("\\*=",    token_ids::times_assign)
+                ("\\/=",    token_ids::divide_assign)
+                ("%=",      token_ids::mod_assign)
+                ("\\&=",    token_ids::bit_and_assign)
+                ("\\^=",    token_ids::bit_xor_assign)
+                ("\\|=",    token_ids::bit_or_assign)
+                ("<<=",     token_ids::shift_left_assign)
+                (">>=",     token_ids::shift_right_assign)
+                ("\\|\\|",  token_ids::logical_or)
+                ("&&",      token_ids::logical_and)
+                ("==",      token_ids::equal)
+                ("!=",      token_ids::not_equal)
+                ("<",       token_ids::less)
+                ("<=",      token_ids::less_equal)
+                (">",       token_ids::greater)
+                (">=",      token_ids::greater_equal)
+                ("\\+",     token_ids::plus)
+                ("\\-",     token_ids::minus)
+                ("\\*",     token_ids::times)
+                ("\\/",     token_ids::divide)
+                ("!",       token_ids::not_)
             ;
 
         this->self += lex::char_('(') | ')' | '{' | '}' | ',' | ';';
 
         this->self +=
                 identifier
-            |   lex::string("\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/", token_ids::comment)
+            |   lex::string("(\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\/)|(\\/\\/[^\r\n]*)", token_ids::comment)
                 [
                     lex::_pass = lex::pass_flags::pass_ignore
                 ]
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/statement_def.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/statement_def.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure3/statement_def.hpp	2011-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
@@ -112,7 +112,12 @@
             error_handler_function(error_handler)(
                 "Error! Expecting ", _4, _3));
 
-        // Annotation: on success in return_statement, call annotation.
+        // Annotation: on success in variable_declaration,
+        // assignment and return_statement, call annotation.
+        on_success(variable_declaration,
+            annotation_function(error_handler.iters)(_val, _1));
+        on_success(assignment,
+            annotation_function(error_handler.iters)(_val, _1));
         on_success(return_statement,
             annotation_function(error_handler.iters)(_val, _1));
     }
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/conjure_samples/error.cnj
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/conjure_samples/error.cnj	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure_samples/error.cnj	2011-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
@@ -1,4 +1,4 @@
-/* mini program with syntax error */
+/* conjure program with syntax error */
 
 int foo(n)
 {
Added: trunk/libs/spirit/example/qi/compiler_tutorial/conjure_samples/operators.cnj
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/conjure_samples/operators.cnj	2011-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
@@ -0,0 +1,90 @@
+/* More operators tests */
+/* Conjure >=3 only!!! */
+
+int plus(x, y)
+{
+    int t = x;
+    t += y;
+    return t;
+}
+
+int minus(x, y)
+{
+    int t = x;
+    t -= y;
+    return t;
+}
+
+int shl(x, y)
+{
+    int t = x;
+    t <<= y;
+    return t;
+}
+
+int div(x, y)
+{
+    int t = x;
+    t /= y;
+    return t;
+}
+
+int mult(x, y)
+{
+    int t = x;
+    t *= y;
+    return t;
+}
+
+int mod(x, y)
+{
+    int t = x;
+    t %= y;
+    return t;
+}
+
+int or(x, y)
+{
+    int t = x;
+    t |= y;
+    return t;
+}
+
+int and(x, y)
+{
+    int t = x;
+    t &= y;
+    return t;
+}
+
+int xor(x, y)
+{
+    int t = x;
+    t ^= y;
+    return t;
+}
+
+int shr(x, y)
+{
+    int t = x;
+    t >>= y;
+    return t;
+}
+
+int main()
+{
+    int a = plus(2, 3);     // 5
+    int b = shl(a, 2);      // 20
+    int c = minus(b, 2);    // 18
+    int d = div(c, 2);      // 9
+    int e = mult(d, c);     // 162
+    int f = mod(e, 10);     // 2
+    int g = or(f, 45);      // 47
+    int h = and(g, 48);     // 32
+    int j = xor(h, h);      // 0
+    int k = or(j, 65535);   // 65535
+    int l = shr(k, 3);      // 8191
+    return l;
+}
+
+
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/mini_c/annotation.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/mini_c/annotation.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/mini_c/annotation.hpp	2011-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
@@ -61,6 +61,13 @@
             boost::apply_visitor(set_id(id), ast);
         }
 
+        void operator()(ast::variable_declaration& ast, Iterator pos) const
+        {
+            int id = iters.size();
+            iters.push_back(pos);
+            ast.lhs.id = id;
+        }
+
         void operator()(ast::assignment& ast, Iterator pos) const
         {
             int id = iters.size();
Modified: trunk/libs/spirit/example/qi/compiler_tutorial/mini_c/statement_def.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/compiler_tutorial/mini_c/statement_def.hpp	(original)
+++ trunk/libs/spirit/example/qi/compiler_tutorial/mini_c/statement_def.hpp	2011-08-05 23:14:47 EDT (Fri, 05 Aug 2011)
@@ -110,7 +110,10 @@
             error_handler_function(error_handler)(
                 "Error! Expecting ", _4, _3));
 
-        // Annotation: on success in assignment, call annotation.
+        // Annotation: on success in variable_declaration,
+        // assignment and return_statement, call annotation.
+        on_success(variable_declaration,
+            annotation_function(error_handler.iters)(_val, _1));
         on_success(assignment,
             annotation_function(error_handler.iters)(_val, _1));
         on_success(return_statement,