Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use early error to avoid ASI for +,-,/, and /= #18

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
124 changes: 113 additions & 11 deletions spec.emu
Original file line number Diff line number Diff line change
Expand Up @@ -351,23 +351,125 @@ contributors: Ron Buckton, Ecma International
[+Await] AwaitExpression[?Yield]

<ins class="block">
ThrowExpressionInvalidPunctuator : one of `,` `&lt;` `>` `&lt;=` `>=` `==` `!=` `===` `!==` `+` `-` `*` `/` `%` `**` `&lt;&lt;` `>>` `>>>` `&` `|` `^` `&&` `||` `??` `=` `+=` `-=` `*=` `/=` `%=` `**=` `&lt;&lt;=` `>>=` `>>>=` `&=` `|=` `^=` `&&=` `||=` `??=` `?`
ThrowExpressionInvalidPunctuator : one of `,` `&lt;` `>` `&lt;=` `>=` `==` `!=` `===` `!==` `*` `%` `**` `&lt;&lt;` `>>` `>>>` `&` `|` `^` `&&` `||` `??` `=` `+=` `-=` `*=` `%=` `**=` `&lt;&lt;=` `>>=` `>>>=` `&=` `|=` `^=` `&&=` `||=` `??=` `?`
</ins>
</emu-grammar>

<emu-clause id="sec-throw-operator">
<h1><ins>The `throw` Operator</ins></h1>
<emu-clause id="sec-throw-operator-runtime-semantics-evaluation">
<h1>Runtime Semantics: Evaluation</h1>
<emu-grammar>UnaryExpression : `throw` UnaryExpression</emu-grammar>
<emu-alg>
1. Let _exprRef_ be ? Evaluation of |UnaryExpression|.
1. Let _exprValue_ be ? GetValue(_exprRef_).
1. Return ThrowCompletion(_exprValue_).
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>

<emu-clause id="sec-throw-operator">
<h1><ins>The `throw` Operator</ins></h1>
<emu-clause id="sec-throw-operator-runtime-semantics-evaluation">
<h1>Runtime Semantics: Evaluation</h1>
<emu-grammar>UnaryExpression : `throw` UnaryExpression</emu-grammar>
<emu-alg>
1. Let _exprRef_ be ? Evaluation of |UnaryExpression|.
1. Let _exprValue_ be ? GetValue(_exprRef_).
1. Return ThrowCompletion(_exprValue_).
</emu-alg>

<emu-clause id="sec-multiplicative-operators">
<h1>Multiplicative Operators</h1>
<emu-clause id="sec-assignment-operators-static-semantics">
<h1>Static Semantics</h1>
<emu-clause id="sec-assignment-operators-static-semantics-early-errors">
<h1>Static Semantics: Early Errors</h1>
<emu-grammar>
MultiplicativeExpression :
MultiplicativeExpression MultiplicativeOperator ExponentiationExpression
</emu-grammar>
<ul>
<li>
It is a Syntax Error if the derived |MultiplicativeExpression| is <emu-grammar>UnaryExpression : `throw` UnaryExpression</emu-grammar> and the source text matched by |MultiplicativeOperator| is `/`.
rbuckton marked this conversation as resolved.
Show resolved Hide resolved
</li>
</ul>
<emu-note>
<p>This production exists in order to prevent automatic semicolon insertion rules (<emu-xref href="#sec-automatic-semicolon-insertion"></emu-xref>) from being applied to the following code:</p>
<pre><code class="javascript">
a ?? throw b
/c/d
</code></pre>
<p>so that it would be interpreted as two valid statements. The purpose is to maintain consistency with similar code using |ThrowStatement|:</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of "maintain consistency" I would say "avoid different valid behaviour", given that we are not consistent with statements because we entirely disallow this case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly, though I'd like an editor to weigh in as I think "maintain consistency" here and in OptionalChain TemplateExpression refers specifically to ASI handling, since both grammars are intended to produce an error.

<pre><code class="javascript">
throw b
/c/d
</code></pre>
<p>which is a valid statement and where automatic semicolon insertion does not apply.</p>
</emu-note>
</emu-clause>
</emu-clause>
</emu-clause>

<emu-clause id="sec-additive-operators">
<h1>Additive Operators</h1>
<emu-clause id="sec-assignment-operators-static-semantics">
<h1>Static Semantics</h1>
<emu-clause id="sec-assignment-operators-static-semantics-early-errors">
<h1>Static Semantics: Early Errors</h1>
<emu-grammar>
AdditiveExpression :
AdditiveExpression `+` MultiplicativeExpression
AdditiveExpression `-` MultiplicativeExpression
</emu-grammar>
<ul>
<li>
It is a Syntax Error if the derived |AdditiveExpression| is <emu-grammar>UnaryExpression : `throw` UnaryExpression</emu-grammar>.
</li>
</ul>
<emu-note>
<p>This production exists in order to prevent automatic semicolon insertion rules (<emu-xref href="#sec-automatic-semicolon-insertion"></emu-xref>) from being applied to the following code:</p>
<pre><code class="javascript">
a ?? throw b
+ c
</code></pre>
<p>so that it would be interpreted as two valid statements. The purpose is to maintain consistency with similar code using |ThrowStatement|:</p>
<pre><code class="javascript">
throw b
+ c
</code></pre>
<p>which is a valid statement and where automatic semicolon insertion does not apply.</p>
</emu-note>
</emu-clause>
</emu-clause>
</emu-clause>

<emu-clause id="sec-assignment-operators">
<h1>Assignment Operators</h1>
<emu-clause id="sec-assignment-operators-static-semantics">
<h1>Static Semantics</h1>
<emu-clause id="sec-assignment-operators-static-semantics-early-errors">
<h1>Static Semantics: Early Errors</h1>
<emu-grammar>
AssignmentExpression :
LeftHandSideExpression `/=` AssignmentExpression
</emu-grammar>
<ul>
<li>
It is a Syntax Error if the derived |LeftHandSideExpression| is <emu-grammar>UnaryExpression : `throw` UnaryExpression</emu-grammar>.
</li>
</ul>
<emu-note>
<p>This production exists in order to prevent automatic semicolon insertion rules (<emu-xref href="#sec-automatic-semicolon-insertion"></emu-xref>) from being applied to the following code:</p>
<pre><code class="javascript">
a ?? throw b
/= c / d
</code></pre>
<p>so that it would be interpreted as two valid statements. The purpose is to maintain consistency with similar code using |ThrowStatement|:</p>
<pre><code class="javascript">
throw b
/= c / d
</code></pre>
<p>which is a valid statement and where automatic semicolon insertion does not apply.</p>
</emu-note>
</emu-clause>
</emu-clause>

</emu-clause>


</emu-clause>
</emu-clause>

<emu-clause id="sec-ecmascript-language-statements-and-declarations">
Expand Down