Skip to content

Commit

Permalink
fix(parser): improved nullish coalescing performance
Browse files Browse the repository at this point in the history
  • Loading branch information
KFlash committed Aug 2, 2019
1 parent f38480d commit 83cbdd5
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 48 deletions.
70 changes: 23 additions & 47 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3264,59 +3264,35 @@ export function parseBinaryExpression(
while (parser.token & Token.IsBinaryOp) {
t = parser.token;
prec = t & Token.Precedence;
// 0 precedence will terminate binary expression parsing
if (prec + (((t === Token.Exponentiate) as any) << 8) - (((bit === t) as any) << 12) <= minPrec) break;
nextToken(parser, context | Context.AllowRegExp);

// Mixing ?? with || or && is currently specified as an early error.
// Since ?? is the lowest-precedence binary operator, it suffices to check whether these ever coexist in the operator stack.
if (
(context & Context.OptionsNext && (t & Token.IsLogical && operator === Token.Coalesce)) ||
(operator & Token.IsLogical && t === Token.Coalesce)
(context & Context.OptionsNext && (t & Token.IsLogical && operator & Token.IsCoalesc)) ||
(operator & Token.IsLogical && t & Token.IsCoalesc)
) {
report(parser, Errors.InvalidCoalescing);
}

left = finishNode(
parser,
context,
start,
line,
column,
context & Context.OptionsNext && t === Token.Coalesce
? {
type: 'CoalesceExpression',
left,
right: parseBinaryExpression(
parser,
context,
inGroup,
parser.tokenPos,
parser.linePos,
parser.colPos,
prec,
t,
parseLeftHandSideExpression(parser, context, 0, inGroup, parser.tokenPos, parser.linePos, parser.colPos)
),
operator: KeywordDescTable[t & Token.Type]
}
: ({
type: t & Token.IsLogical ? 'LogicalExpression' : 'BinaryExpression',
left,
right: parseBinaryExpression(
parser,
context,
inGroup,
parser.tokenPos,
parser.linePos,
parser.colPos,
prec,
t,
parseLeftHandSideExpression(parser, context, 0, inGroup, parser.tokenPos, parser.linePos, parser.colPos)
),
operator: KeywordDescTable[t & Token.Type]
} as any)
);
// 0 precedence will terminate binary expression parsing

if (prec + (((t === Token.Exponentiate) as any) << 8) - (((bit === t) as any) << 12) <= minPrec) break;
nextToken(parser, context | Context.AllowRegExp);

left = finishNode(parser, context, start, line, column, {
type: t & Token.IsLogical ? 'LogicalExpression' : t & Token.IsCoalesc ? 'CoalesceExpression' : 'BinaryExpression',
left,
right: parseBinaryExpression(
parser,
context,
inGroup,
parser.tokenPos,
parser.linePos,
parser.colPos,
prec,
t,
parseLeftHandSideExpression(parser, context, 0, inGroup, parser.tokenPos, parser.linePos, parser.colPos)
),
operator: KeywordDescTable[t & Token.Type]
} as any);
}

if (parser.token === Token.Assign) report(parser, Errors.CantAssignTo);
Expand Down
3 changes: 2 additions & 1 deletion src/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const enum Token {
VarDecl = 1 << 28,
IsEvalOrArguments = 1 << 29 | IsExpressionStart | IsIdentifier,
IsClassField = 1 << 30,
IsCoalesc = 1 << 31,

/* Node types */
EOF = 0 | IsAutoSemicolon,
Expand Down Expand Up @@ -186,7 +187,7 @@ export const enum Token {
JSXText = 137,

// Stage #3 proposals
Coalesce = 123 | IsBinaryOp | 1 << PrecStart, // ??
Coalesce = 123 | IsBinaryOp | IsCoalesc | 1 << PrecStart, // ??
}

export const KeywordDescTable = [
Expand Down

0 comments on commit 83cbdd5

Please sign in to comment.