The following code...
Assume that the yield is inside a generator function and that something
and else
are defined, etc.
const value = something || yield else();
...produces the following in V8 (Chrome or Nodejs):
const start = initial || yield wait();
^^^^^
SyntaxError: Unexpected strict mode reserved word
...and this in Firefox:
SyntaxError: yield is a reserved identifier
I first noticed this in a bluebird coroutine I was writing. The fix is to wrap the yield wait()
in a parentheses.
This error happens at parse time rather than at execution time; so, my first assumption is that this is because there's a syntactic ambiguity here. I looked at the yield keyword which defines it as:
[rv] = yield [expression];
yield
takes an expression and returns a value. This does not happen without the ||
(OR) operator as const value = yield else();
; so, I looked at operator precedence. The ||
(OR) operator is evaluated at 5 before the yield
operator at 2. The precedence looks fine.
It looks like the ||
(OR) operator requires an expression on either side and while I assume that yield [expression]
is an expression, perhaps that's not true? Why is it that I need to wrap that part in parentheses to make it explicitly an expression? What could || yield
be ambiguous with? I'm sure I'm just missing it; or, is there some sneaky/deeper reason for this?
This question was also notoriously difficult to search for, so hopefully I'm not duping here.
(You can use this Plunker https://plnkr.co/edit/rNidnFuyIOFkRkkcyWRV to make the error happen if you'd like to see it.)
Thanks!
If you want to figure out the syntax rules, you have to look at the spec.
A LogicalOrExpression is defined as
LogicalANDExpression:
BitwiseORExpression
LogicalANDExpression && BitwiseORExpression
LogicalORExpression:
LogicalANDExpression
LogicalORExpression || LogicalANDExpression
A LogicalANDExpression can only contain BitwiseORExpressions. But a YieldExpression is not a BitwiseORExpression, it's an AssignmentExpression:
AssignmentExpression:
ConditionalExpression
[+Yield] YieldExpression
ArrowFunction
LeftHandSideExpression = AssignmentExpression
LeftHandSideExpression AssignmentOperatorAssignmentExpression
It basically it is higher up in the expression hierarchy:
+--------------------------+
| AssignmentExpression |
+--------------------------+
^
|
+----------------+---------------+
| |
| |
+--------------------------+ +--------------------------+
| ConditionalExpression | | YieldExpression |
+--------------------------+ +--------------------------+
^
|
|
+--------------------------+
| LogicalORExpression |
+--------------------------+
^
|
|
+--------------------------+
| LogicalANDExpression |
+--------------------------+
^
|
|
+--------------------------+
| BitwiseORExpression |
+--------------------------+
A possibly explanation for why the syntax is structured this way is that yield
is also a valid identifier name (outside of generators or yield expressions). But for more details you probably want to ask on https://esdiscuss.org/.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With