mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
LibJS: Parse comma operator into SequenceExpression
This commit is contained in:
parent
71fd752289
commit
8ffdcce0d0
Notes:
sideshowbarker
2024-07-19 06:43:21 +09:00
Author: https://github.com/linusg Commit: https://github.com/SerenityOS/serenity/commit/8ffdcce0d01 Pull-request: https://github.com/SerenityOS/serenity/pull/2193
2 changed files with 48 additions and 13 deletions
|
@ -299,7 +299,7 @@ RefPtr<FunctionExpression> Parser::try_parse_arrow_function_expression(bool expe
|
|||
if (expect_parens && match(TokenType::Equals)) {
|
||||
consume(TokenType::Equals);
|
||||
function_length = parameters.size();
|
||||
default_value = parse_expression(0);
|
||||
default_value = parse_expression(2);
|
||||
}
|
||||
parameters.append({ parameter_name, default_value });
|
||||
} else if (match(TokenType::TripleDot)) {
|
||||
|
@ -340,7 +340,7 @@ RefPtr<FunctionExpression> Parser::try_parse_arrow_function_expression(bool expe
|
|||
if (parse_failed)
|
||||
return nullptr;
|
||||
|
||||
if (function_length == -1)
|
||||
if (function_length == -1)
|
||||
function_length = parameters.size();
|
||||
|
||||
auto function_body_result = [this]() -> RefPtr<BlockStatement> {
|
||||
|
@ -504,7 +504,7 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
|||
consume(TokenType::BracketClose);
|
||||
} else if (match(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;
|
||||
need_colon = false;
|
||||
is_spread = true;
|
||||
|
@ -518,7 +518,7 @@ NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
|
|||
property_value = parse_function_node<FunctionExpression>(false);
|
||||
} else if (need_colon || match(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);
|
||||
properties.append(property);
|
||||
|
@ -545,9 +545,9 @@ NonnullRefPtr<ArrayExpression> Parser::parse_array_expression()
|
|||
|
||||
if (match(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()) {
|
||||
expression = parse_expression(0);
|
||||
expression = parse_expression(2);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -795,9 +804,9 @@ NonnullRefPtr<CallExpression> Parser::parse_call_expression(NonnullRefPtr<Expres
|
|||
while (match_expression() || match(TokenType::TripleDot)) {
|
||||
if (match(TokenType::TripleDot)) {
|
||||
consume();
|
||||
arguments.append({ parse_expression(0), true });
|
||||
arguments.append({ parse_expression(2), true });
|
||||
} else {
|
||||
arguments.append({ parse_expression(0), false });
|
||||
arguments.append({ parse_expression(2), false });
|
||||
}
|
||||
if (!match(TokenType::Comma))
|
||||
break;
|
||||
|
@ -823,9 +832,9 @@ NonnullRefPtr<NewExpression> Parser::parse_new_expression()
|
|||
while (match_expression() || match(TokenType::TripleDot)) {
|
||||
if (match(TokenType::TripleDot)) {
|
||||
consume();
|
||||
arguments.append({ parse_expression(0), true });
|
||||
arguments.append({ parse_expression(2), true });
|
||||
} else {
|
||||
arguments.append({ parse_expression(0), false });
|
||||
arguments.append({ parse_expression(2), false });
|
||||
}
|
||||
if (!match(TokenType::Comma))
|
||||
break;
|
||||
|
@ -906,7 +915,7 @@ NonnullRefPtr<FunctionNodeType> Parser::parse_function_node(bool needs_function_
|
|||
if (match(TokenType::Equals)) {
|
||||
consume(TokenType::Equals);
|
||||
function_length = parameters.size();
|
||||
default_value = parse_expression(0);
|
||||
default_value = parse_expression(2);
|
||||
}
|
||||
parameters.append({ parameter_name, default_value });
|
||||
if (match(TokenType::ParenClose))
|
||||
|
@ -917,7 +926,7 @@ NonnullRefPtr<FunctionNodeType> Parser::parse_function_node(bool needs_function_
|
|||
|
||||
if (function_length == -1)
|
||||
function_length = parameters.size();
|
||||
|
||||
|
||||
auto body = parse_block_statement();
|
||||
body->add_variables(m_parser_state.m_var_scopes.last());
|
||||
return create_ast_node<FunctionNodeType>(name, move(body), move(parameters), function_length, NonnullRefPtrVector<VariableDeclaration>());
|
||||
|
@ -950,7 +959,7 @@ NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration()
|
|||
RefPtr<Expression> init;
|
||||
if (match(TokenType::Equals)) {
|
||||
consume();
|
||||
init = parse_expression(0);
|
||||
init = parse_expression(2);
|
||||
}
|
||||
declarations.append(create_ast_node<VariableDeclarator>(create_ast_node<Identifier>(move(id)), move(init)));
|
||||
if (match(TokenType::Comma)) {
|
||||
|
|
26
Libraries/LibJS/Tests/comma-operator.js
Normal file
26
Libraries/LibJS/Tests/comma-operator.js
Normal 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);
|
||||
}
|
Loading…
Reference in a new issue