diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index 1394c5dc05..436980ec55 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -383,6 +383,22 @@ Value AssignmentExpression::execute(Interpreter& interpreter) const case AssignmentOp::Assign: interpreter.set_variable(name, rhs_result); break; + case AssignmentOp::PlusEquals: + rhs_result = add(m_lhs->execute(interpreter), rhs_result); + interpreter.set_variable(name, rhs_result); + break; + case AssignmentOp::MinusEquals: + rhs_result = sub(m_lhs->execute(interpreter), rhs_result); + interpreter.set_variable(name, rhs_result); + break; + case AssignmentOp::AsteriskEquals: + rhs_result = mul(m_lhs->execute(interpreter), rhs_result); + interpreter.set_variable(name, rhs_result); + break; + case AssignmentOp::SlashEquals: + rhs_result = div(m_lhs->execute(interpreter), rhs_result); + interpreter.set_variable(name, rhs_result); + break; } return rhs_result; } @@ -394,6 +410,18 @@ void AssignmentExpression::dump(int indent) const case AssignmentOp::Assign: op_string = "="; break; + case AssignmentOp::PlusEquals: + op_string = "+="; + break; + case AssignmentOp::MinusEquals: + op_string = "-="; + break; + case AssignmentOp::AsteriskEquals: + op_string = "*="; + break; + case AssignmentOp::SlashEquals: + op_string = "/="; + break; } ASTNode::dump(indent); diff --git a/Libraries/LibJS/AST.h b/Libraries/LibJS/AST.h index decfa5137b..6c3f11b8f1 100644 --- a/Libraries/LibJS/AST.h +++ b/Libraries/LibJS/AST.h @@ -391,6 +391,10 @@ private: enum class AssignmentOp { Assign, + PlusEquals, + MinusEquals, + AsteriskEquals, + SlashEquals, }; class AssignmentExpression : public Expression { diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index 38e278300c..c022b96b6c 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -124,15 +124,27 @@ NonnullOwnPtr Parser::parse_secondary_expression(NonnullOwnPtr(BinaryOp::Plus, move(lhs), parse_expression()); + case TokenType::PlusEquals: + consume(); + return make(AssignmentOp::PlusEquals, move(lhs), parse_expression()); case TokenType::Minus: consume(); return make(BinaryOp::Minus, move(lhs), parse_expression()); + case TokenType::MinusEquals: + consume(); + return make(AssignmentOp::MinusEquals, move(lhs), parse_expression()); case TokenType::Asterisk: consume(); return make(BinaryOp::Asterisk, move(lhs), parse_expression()); + case TokenType::AsteriskEquals: + consume(); + return make(AssignmentOp::AsteriskEquals, move(lhs), parse_expression()); case TokenType::Slash: consume(); return make(BinaryOp::Slash, move(lhs), parse_expression()); + case TokenType::SlashEquals: + consume(); + return make(AssignmentOp::SlashEquals, move(lhs), parse_expression()); case TokenType::GreaterThanEquals: consume(); return make(BinaryOp::GreaterThanEquals, move(lhs), parse_expression()); @@ -250,9 +262,13 @@ bool Parser::match_secondary_expression() const { auto type = m_current_token.type(); return type == TokenType::Plus + || type == TokenType::PlusEquals || type == TokenType::Minus + || type == TokenType::MinusEquals || type == TokenType::Asterisk + || type == TokenType::AsteriskEquals || type == TokenType::Slash + || type == TokenType::SlashEquals || type == TokenType::Equals || type == TokenType::GreaterThanEquals || type == TokenType::LessThanEquals