<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -88,6 +88,8 @@ static int line_pop();
 %nonassoc '?' '|'
 %left   tOR tAND
 %left   tEQ tNE '&lt;' tLE '&gt;' tGE tIN
+%left   tOREQ tANDEQ tORASSIGN
+%left   tADDEQ tSUBEQ tMULEQ tDIVEQ
 %left   '+' '-'
 %left   '*' '/' '%'
 %right  '^'
@@ -282,6 +284,41 @@ expr:
             // Handle this in the compiler... bah
             $$ = rb_ary_new3(3,ID2SYM(rb_intern(&quot;assign&quot;)),$1,$3);
         }
+    | expr tORASSIGN expr
+        {
+            // Handle / expand this in the compiler... bah
+            $$ = rb_ary_new3(4,ID2SYM(rb_intern(&quot;condition&quot;)),$1,$1,rb_ary_new3(3,ID2SYM(rb_intern(&quot;assign&quot;)),$1,$3));
+        }
+    | expr tADDEQ expr
+        {
+            // This could probably be done as an opcode, but
+            $$ = rb_ary_new3(3,ID2SYM(rb_intern(&quot;assign&quot;)),$1,rb_ary_new3(3,ID2SYM(rb_intern(&quot;plus&quot;)),$1,$3));
+        }
+    | expr tSUBEQ expr
+        {
+            // This could probably be done as an opcode, but
+            $$ = rb_ary_new3(3,ID2SYM(rb_intern(&quot;assign&quot;)),$1,rb_ary_new3(3,ID2SYM(rb_intern(&quot;minus&quot;)),$1,$3));
+        }
+    | expr tMULEQ expr
+        {
+            // This could probably be done as an opcode, but
+            $$ = rb_ary_new3(3,ID2SYM(rb_intern(&quot;assign&quot;)),$1,rb_ary_new3(3,ID2SYM(rb_intern(&quot;multiply&quot;)),$1,$3));
+        }
+    | expr tDIVEQ expr
+        {
+            // This could probably be done as an opcode, but
+            $$ = rb_ary_new3(3,ID2SYM(rb_intern(&quot;assign&quot;)),$1,rb_ary_new3(3,ID2SYM(rb_intern(&quot;divide&quot;)),$1,$3));
+        }
+    | expr tANDEQ expr
+        {
+            // This could probably be done as an opcode, but
+            $$ = rb_ary_new3(3,ID2SYM(rb_intern(&quot;assign&quot;)),$1,rb_ary_new3(3,ID2SYM(rb_intern(&quot;and&quot;)),$1,$3));
+        }
+    | expr tOREQ expr
+        {
+            // This could probably be done as an opcode, but
+            $$ = rb_ary_new3(3,ID2SYM(rb_intern(&quot;assign&quot;)),$1,rb_ary_new3(3,ID2SYM(rb_intern(&quot;or&quot;)),$1,$3));
+        }
     | '{' scatter '}' '=' expr
         {
             // Handle this in the compiler... bah
@@ -603,8 +640,27 @@ start_over:
                                 ? c
                                 : follow('&gt;', tARROW, '='));
       case '!':         return follow('=', tNE, '!');
-      case '|':         return follow('|', tOR, '|');
-      case '&amp;':         return follow('&amp;', tAND, '&amp;');
+      case '|':         {
+        int c2 = lex_getc();
+        if (c2 == '=')
+          return tOREQ;
+        else if (c2 == '|') {
+          int c3 = lex_getc();
+          if (c3 == '=')
+            return tORASSIGN;
+          lex_ungetc(c3);
+          return tOR;
+         } else {
+            lex_ungetc(c2);
+            return '|';
+         }
+      }
+      case '&amp;':         return follow('&amp;', tAND, follow('=', tANDEQ, '&amp;'));
+
+      case '+':         return follow('=', tADDEQ, '+');
+      case '-':         return follow('=', tSUBEQ, '-');
+      case '*':         return follow('=', tMULEQ, '*');
+      case '/':         return follow('=', tDIVEQ, '/');
 normal_dot:
       case '.':         return follow('.', tTO, '.');
       default:          return c;</diff>
      <filename>ext/parser/grammar.y</filename>
    </modified>
    <modified>
      <diff>@@ -189,6 +189,8 @@ module Moo
           elsif (stmt == :try_finally)
             item[1] = __stmt(item[1],block,data)
             item[2] = __stmt(item[2],block,data)
+          else
+            throw &quot;HANDLER MISSING #{k[0]}&quot;
           end
           data[:what] = :stmt_keep
           data[:item] = into[i]</diff>
      <filename>lib/moo/language/optimizer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -59,6 +59,28 @@ class TestParser &lt; Test::Unit::TestCase
     ], p);
   end
   
+  def test_modern_ops
+    p = Moo::Language::Parser::Native::parse Moo::Language::Parser::StringStream.new(%q{
+      a += 1;
+      a -= 1;
+      a *= 1;
+      
+      
+      a |= 1;
+      a &amp;= 1;
+      
+      a ||= 1;
+    })
+    assert_equal([
+      [:expr, [:assign,[:id,'a'],[:plus,[:id,'a'],1]],2],
+      [:expr, [:assign,[:id,'a'],[:minus,[:id,'a'],1]],3],
+      [:expr, [:assign,[:id,'a'],[:multiply,[:id,'a'],1]],4],
+      [:expr, [:assign,[:id,'a'],[:or,[:id,'a'],1]],7],
+      [:expr, [:assign,[:id,'a'],[:and,[:id,'a'],1]],8],
+      [:expr, [:condition,[:id,'a'],[:id,'a'],[:assign,[:id,&quot;a&quot;],1]],10],
+    ], p);
+  end
+  
   def test_return
     p = Moo::Language::Parser::Native::parse Moo::Language::Parser::StringStream.new(&quot;return;&quot;)
     assert_equal([[:return,nil,1]], p);</diff>
      <filename>test/test_parser.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>86f613eae179f8f1dba1a089f0121825b5d891d3</id>
    </parent>
  </parents>
  <author>
    <name>Andrea Nall</name>
    <email>anall@andreanall.com</email>
  </author>
  <url>http://github.com/anall/ruby-moo/commit/70caea43cfc76dbb3fabf00e8761c6057722a378</url>
  <id>70caea43cfc76dbb3fabf00e8761c6057722a378</id>
  <committed-date>2009-06-01T03:51:43-07:00</committed-date>
  <authored-date>2009-06-01T03:51:43-07:00</authored-date>
  <message>Modern ops +=, -=, *=, &amp;=, |=, ||=

(/= doesn't work yet, and syntax errors)</message>
  <tree>2d4eb6822ebbf6c72d780be4457d290d1318b9f5</tree>
  <committer>
    <name>Andrea Nall</name>
    <email>anall@andreanall.com</email>
  </committer>
</commit>
