mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +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)) {
|
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)) {
|
||||||
|
|
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