michaelficarra/CoffeeScriptRedux — pull request #189 by heartsentwined (2013-04-06 16:51:19+00:00)
Title: test for assignment + logical operators precedence

This PR adds test cases demonstrating an assignment operator vs logical
operator precedence issue / behavior.

# The issue

Compile errors first:

```
Syntax error on line 1, column 21: unexpected '=' (\u003D)
1 : true if true && foo = 'bar'
^ :~~~~~~~~~~~~~~~~~~~~~^
2 :
```

(`foo` should be assigned the value of `'bar'`.)

```
Syntax error on line 1, column 21: unexpected '=' (\u003D)
1 : true if true && foo = 'bar' && true
^ :~~~~~~~~~~~~~~~~~~~~~^
2 :
```

(`foo` should be assigned the value of `true`.)

Similar errors tested for `and`, `||` and `or`.

All compile fine in the original coffeescript compiler.

For compleness, this works fine:

```
true if foo = 'bar' && true
```

# Existing workaround

Adding parens to group the assignment `foo = 'bar'` fixes all cases:

```coffeescript
true if true && (foo = 'bar')
true if true && (foo = 'bar' && true)
```

# Syntax discussion

I believe that this is an operator precedence issue. While logical operators
should, of course, normally take precedence over assignment operators, this
should only happen when the logical operator appears at the right hand side
of the assignment operator.

Given
```coffeescript
true || foo = 'bar' && true
```

While the `&&` operator taking precedence over the assignment operator makes
sense, the case of the `||` operator would produce this semantically invalid
parsing:

```coffeescript
(true) = (true)
```

Since all logical operators will produce a boolean primitive, and that boolean
primitives cannot be the receiver of the assignment operator, an exception
should be made to change the operator precedence on such cases, producing:

```coffeescript
(true) || (foo = true)
```

I'm sorry but I am not familiar with pegjs, so I can only produce a test case
in this PR accompanied by this description.