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)
newwithout its(..)args is level 16so
new foo'hi'should result infoo'hi'being evaluated firstthen
newis 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_expressionsrequire anexpression, butnew_expressionsonly allowprimary_expressionsso when theidentifierfoois processed into aprimary_expressionit gets consumed bynew_expressionwithout conflict.This diff changes
call_expressionsto 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_expressionallows forcall_expressionmember_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_callprecedence for this case.Note that regular
callprecedences should still come after 'new' so thatnew foo()continues to parse correctlycc @amaanq