LibJS: Parse comma operator into SequenceExpression

This commit is contained in:
Linus Groh 2020-05-11 17:27:31 +01:00 committed by Andreas Kling
parent 71fd752289
commit 8ffdcce0d0
Notes: sideshowbarker 2024-07-19 06:43:21 +09:00
2 changed files with 48 additions and 13 deletions

View file

@ -299,7 +299,7 @@ RefPtr<FunctionExpression> Parser::try_parse_arrow_function_expression(bool expe
if (expect_parens && match(TokenType::Equals)) { if (expect_parens && match(TokenType::Equals)) {
consume(TokenType::Equals); consume(TokenType::Equals);
function_length = parameters.size(); function_length = parameters.size();
default_value = parse_expression(0); default_value = parse_expression(2);
} }
parameters.append({ parameter_name, default_value }); parameters.append({ parameter_name, default_value });
} else if (match(TokenType::TripleDot)) { } else if (match(TokenType::TripleDot)) {
@ -504,7 +504,7 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
consume(TokenType::BracketClose); consume(TokenType::BracketClose);
} else if (match(TokenType::TripleDot)) { } else if (match(TokenType::TripleDot)) {
consume(TokenType::TripleDot); consume(TokenType::TripleDot);
property_key = create_ast_node<SpreadExpression>(parse_expression(0)); property_key = create_ast_node<SpreadExpression>(parse_expression(2));
property_value = property_key; property_value = property_key;
need_colon = false; need_colon = false;
is_spread = true; is_spread = true;
@ -518,7 +518,7 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
property_value = parse_function_node<FunctionExpression>(false); property_value = parse_function_node<FunctionExpression>(false);
} else if (need_colon || match(TokenType::Colon)) { } else if (need_colon || match(TokenType::Colon)) {
consume(TokenType::Colon); consume(TokenType::Colon);
property_value = parse_expression(0); property_value = parse_expression(2);
} }
auto property = create_ast_node<ObjectProperty>(*property_key, *property_value); auto property = create_ast_node<ObjectProperty>(*property_key, *property_value);
properties.append(property); properties.append(property);
@ -545,9 +545,9 @@ NonnullRefPtr<ArrayExpression> Parser::parse_array_expression()
if (match(TokenType::TripleDot)) { if (match(TokenType::TripleDot)) {
consume(TokenType::TripleDot); consume(TokenType::TripleDot);
expression = create_ast_node<SpreadExpression>(parse_expression(0)); expression = create_ast_node<SpreadExpression>(parse_expression(2));
} else if (match_expression()) { } else if (match_expression()) {
expression = parse_expression(0); expression = parse_expression(2);
} }
elements.append(expression); elements.append(expression);
@ -634,6 +634,15 @@ NonnullRefPtr<Expression> Parser::parse_expression(int min_precedence, Associati
expression = create_ast_node<TaggedTemplateLiteral>(move(expression), move(template_literal)); expression = create_ast_node<TaggedTemplateLiteral>(move(expression), move(template_literal));
} }
} }
if (match(TokenType::Comma) && min_precedence <= 1) {
NonnullRefPtrVector<Expression> expressions;
expressions.append(expression);
while (match(TokenType::Comma)) {
consume();
expressions.append(parse_expression(2));
}
expression = create_ast_node<SequenceExpression>(move(expressions));
}
return expression; return expression;
} }
@ -795,9 +804,9 @@ NonnullRefPtr<CallExpression> Parser::parse_call_expression(NonnullRefPtr<Expres
while (match_expression() || match(TokenType::TripleDot)) { while (match_expression() || match(TokenType::TripleDot)) {
if (match(TokenType::TripleDot)) { if (match(TokenType::TripleDot)) {
consume(); consume();
arguments.append({ parse_expression(0), true }); arguments.append({ parse_expression(2), true });
} else { } else {
arguments.append({ parse_expression(0), false }); arguments.append({ parse_expression(2), false });
} }
if (!match(TokenType::Comma)) if (!match(TokenType::Comma))
break; break;
@ -823,9 +832,9 @@ NonnullRefPtr<NewExpression> Parser::parse_new_expression()
while (match_expression() || match(TokenType::TripleDot)) { while (match_expression() || match(TokenType::TripleDot)) {
if (match(TokenType::TripleDot)) { if (match(TokenType::TripleDot)) {
consume(); consume();
arguments.append({ parse_expression(0), true }); arguments.append({ parse_expression(2), true });
} else { } else {
arguments.append({ parse_expression(0), false }); arguments.append({ parse_expression(2), false });
} }
if (!match(TokenType::Comma)) if (!match(TokenType::Comma))
break; break;
@ -906,7 +915,7 @@ NonnullRefPtr<FunctionNodeType> Parser::parse_function_node(bool needs_function_
if (match(TokenType::Equals)) { if (match(TokenType::Equals)) {
consume(TokenType::Equals); consume(TokenType::Equals);
function_length = parameters.size(); function_length = parameters.size();
default_value = parse_expression(0); default_value = parse_expression(2);
} }
parameters.append({ parameter_name, default_value }); parameters.append({ parameter_name, default_value });
if (match(TokenType::ParenClose)) if (match(TokenType::ParenClose))
@ -950,7 +959,7 @@ NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration()
RefPtr<Expression> init; RefPtr<Expression> init;
if (match(TokenType::Equals)) { if (match(TokenType::Equals)) {
consume(); consume();
init = parse_expression(0); init = parse_expression(2);
} }
declarations.append(create_ast_node<VariableDeclarator>(create_ast_node<Identifier>(move(id)), move(init))); declarations.append(create_ast_node<VariableDeclarator>(create_ast_node<Identifier>(move(id)), move(init)));
if (match(TokenType::Comma)) { if (match(TokenType::Comma)) {

View file

@ -0,0 +1,26 @@
load("test-common.js");
try {
assert((1, 2, 3) === 3);
assert((1, 2 + 3, 4) === 4);
var foo = 0;
foo = (foo++, foo);
assert(foo === 1);
var a, b, c;
assert((a = b = 3, c = 4) === 4);
assert(a === 3);
assert(b === 3);
assert(c === 4);
var x, y, z;
assert((x = (y = 5, z = 6)) === 6);
assert(x === 6)
assert(y === 5)
assert(z === 6)
console.log("PASS");
} catch (e) {
console.log("FAIL: " + e);
}