mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 17:10:23 +00:00
LibJS: Fix broken parsing of !o.a
Unary expressions parsing now respects precedence and associativity of operators. This patch also makes `typeof` left-associative which was an oversight. Thanks to Conrad for helping me work this out. :^)
This commit is contained in:
parent
f1a074a262
commit
14de45296e
Notes:
sideshowbarker
2024-07-19 08:05:55 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/14de45296eb
2 changed files with 26 additions and 5 deletions
|
@ -150,6 +150,7 @@ Associativity Parser::operator_associativity(TokenType type) const
|
|||
case TokenType::ExclamationMarkEquals:
|
||||
case TokenType::EqualsEqualsEquals:
|
||||
case TokenType::ExclamationMarkEqualsEquals:
|
||||
case TokenType::Typeof:
|
||||
case TokenType::Ampersand:
|
||||
case TokenType::Caret:
|
||||
case TokenType::Pipe:
|
||||
|
@ -256,22 +257,24 @@ NonnullRefPtr<Expression> Parser::parse_primary_expression()
|
|||
|
||||
NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression()
|
||||
{
|
||||
auto precedence = operator_precedence(m_current_token.type());
|
||||
auto associativity = operator_associativity(m_current_token.type());
|
||||
switch (m_current_token.type()) {
|
||||
case TokenType::PlusPlus:
|
||||
consume();
|
||||
return create_ast_node<UpdateExpression>(UpdateOp::Increment, parse_primary_expression(), true);
|
||||
return create_ast_node<UpdateExpression>(UpdateOp::Increment, parse_expression(precedence, associativity), true);
|
||||
case TokenType::MinusMinus:
|
||||
consume();
|
||||
return create_ast_node<UpdateExpression>(UpdateOp::Decrement, parse_primary_expression(), true);
|
||||
return create_ast_node<UpdateExpression>(UpdateOp::Decrement, parse_expression(precedence, associativity), true);
|
||||
case TokenType::ExclamationMark:
|
||||
consume();
|
||||
return create_ast_node<UnaryExpression>(UnaryOp::Not, parse_primary_expression());
|
||||
return create_ast_node<UnaryExpression>(UnaryOp::Not, parse_expression(precedence, associativity));
|
||||
case TokenType::Tilde:
|
||||
consume();
|
||||
return create_ast_node<UnaryExpression>(UnaryOp::BitwiseNot, parse_primary_expression());
|
||||
return create_ast_node<UnaryExpression>(UnaryOp::BitwiseNot, parse_expression(precedence, associativity));
|
||||
case TokenType::Typeof:
|
||||
consume();
|
||||
return create_ast_node<UnaryExpression>(UnaryOp::Typeof, parse_primary_expression());
|
||||
return create_ast_node<UnaryExpression>(UnaryOp::Typeof, parse_expression(precedence, associativity));
|
||||
default:
|
||||
m_has_errors = true;
|
||||
expected("primary expression (missing switch case)");
|
||||
|
|
18
Libraries/LibJS/Tests/parser-unary-associativity.js
Normal file
18
Libraries/LibJS/Tests/parser-unary-associativity.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
function assert(x) { if (!x) throw 1; }
|
||||
|
||||
try {
|
||||
var o = {};
|
||||
o.a = 1;
|
||||
|
||||
assert(o.a === 1);
|
||||
assert(!o.a === false);
|
||||
assert(!o.a === !(o.a));
|
||||
assert(~o.a === ~(o.a));
|
||||
|
||||
assert((typeof "x" === "string") === true);
|
||||
assert(!(typeof "x" === "string") === false);
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL: " + e);
|
||||
}
|
Loading…
Reference in a new issue