diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index eea7b0ef92..9884ec430f 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -233,6 +233,29 @@ NonnullOwnPtr Parser::parse_primary_expression() } } +NonnullOwnPtr Parser::parse_unary_prefixed_expression() +{ + switch (m_current_token.type()) { + case TokenType::PlusPlus: + consume(); + return make(UpdateOp::Increment, parse_primary_expression(), true); + case TokenType::MinusMinus: + consume(); + return make(UpdateOp::Decrement, parse_primary_expression(), true); + case TokenType::ExclamationMark: + consume(); + return make(UnaryOp::Not, parse_primary_expression()); + case TokenType::Tilde: + consume(); + return make(UnaryOp::BitwiseNot, parse_primary_expression()); + default: + m_has_errors = true; + expected("primary expression (missing switch case)"); + consume(); + return make(); + } +} + NonnullOwnPtr Parser::parse_object_expression() { // FIXME: Parse actual object expression @@ -243,6 +266,9 @@ NonnullOwnPtr Parser::parse_object_expression() NonnullOwnPtr Parser::parse_expression(int min_precedence, Associativity associativity) { + if (match_unary_prefixed_expression()) + return parse_unary_prefixed_expression(); + auto expression = parse_primary_expression(); while (match_secondary_expression()) { int new_precedence = operator_precedence(m_current_token.type()); @@ -477,7 +503,17 @@ bool Parser::match_expression() const || type == TokenType::New || type == TokenType::CurlyOpen || type == TokenType::BracketOpen - || type == TokenType::ParenOpen; + || type == TokenType::ParenOpen + || match_unary_prefixed_expression(); +} + +bool Parser::match_unary_prefixed_expression() const +{ + auto type = m_current_token.type(); + return type == TokenType::PlusPlus + || type == TokenType::MinusMinus + || type == TokenType::ExclamationMark + || type == TokenType::Tilde; } bool Parser::match_secondary_expression() const diff --git a/Libraries/LibJS/Parser.h b/Libraries/LibJS/Parser.h index 314c636aec..003a4ea2fb 100644 --- a/Libraries/LibJS/Parser.h +++ b/Libraries/LibJS/Parser.h @@ -52,6 +52,7 @@ public: NonnullOwnPtr parse_expression(int min_precedence, Associativity associate = Associativity::Right); NonnullOwnPtr parse_primary_expression(); + NonnullOwnPtr parse_unary_prefixed_expression(); NonnullOwnPtr parse_object_expression(); NonnullOwnPtr parse_secondary_expression(NonnullOwnPtr, int min_precedence, Associativity associate = Associativity::Right); NonnullOwnPtr parse_call_expression(NonnullOwnPtr); @@ -62,6 +63,7 @@ private: int operator_precedence(TokenType) const; Associativity operator_associativity(TokenType) const; bool match_expression() const; + bool match_unary_prefixed_expression() const; bool match_secondary_expression() const; bool match_statement() const; bool match(TokenType type) const;