Fix: Operator precedence rules for tagged template functions #336
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Closes #334
Background understanding
(FYI i'm using
'
as a backtick in in-line code blocks for convenience, whenever i use single-quote, i mean backtick)Tagged templates have operator precedence ~16 according to MDN (src)
new
without its(..)
args is level 16so
new foo'hi'
should result infoo'hi'
being evaluated firstthen
new
is applied as if the result offoo'hi'
is a classnameSo the correct parse tree should be something like this
but
new()
with its args list is level 17so
new foo()'hi'
should result innew foo()
being evaluated firstthen
'hi'
being applied as it 'calls' the resulting class instanceSo the correct parse tree should be something like this
Current Problem and fix
new foo()'hi'
is currently correct butnew foo'hi'
results inThis occurs for two reasons,
call_expressions
require anexpression
, butnew_expressions
only allowprimary_expressions
so when theidentifier
foo
is processed into aprimary_expression
it gets consumed bynew_expression
without conflict.This diff changes
call_expressions
to be constructed withchoice(primary_expression, new_expression)
in the case where a tagged-template is used. This is sane because of the precedence rules discussed earlier, ieprimary_expression
allows forcall_expression
member_expression
(level 17),parenthesized_expression
(level 18), and direct identifiers.The only other allowed expression is
new_expression
(level 17) so I added it to the choice blockWith this change, we still don't get the desired result because 'new' primary_expression gets resolved as new_expression before we can make a call expression. So I add a new
template_call
precedence for this case.Note that regular
call
precedences should still come after 'new' so thatnew foo()
continues to parse correctlycc @amaanq