diff options
author | Andreas Kling <kling@serenityos.org> | 2020-03-28 11:48:52 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-03-28 11:51:44 +0100 |
commit | 14de45296eb93a42282782769b03e2e42739a2aa (patch) | |
tree | 5a1aa57d443ceacdf267bb87bf75639486abe995 /Libraries/LibJS/Parser.cpp | |
parent | f1a074a262a9815a1063b17d20df1d1a15308cef (diff) | |
download | serenity-14de45296eb93a42282782769b03e2e42739a2aa.zip |
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. :^)
Diffstat (limited to 'Libraries/LibJS/Parser.cpp')
-rw-r--r-- | Libraries/LibJS/Parser.cpp | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index ef0791622b..c4f2a3966f 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -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)"); |