mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 21:27:44 +00:00
LibJS: Implement exponentiation assignment operator (**=)
This commit is contained in:
parent
3e754a15d4
commit
a2e1f1a872
8 changed files with 23 additions and 5 deletions
|
@ -62,7 +62,7 @@ static TextStyle style_for_token_type(Gfx::Palette palette, JS::TokenType type)
|
||||||
case JS::TokenType::Ampersand:
|
case JS::TokenType::Ampersand:
|
||||||
case JS::TokenType::AmpersandEquals:
|
case JS::TokenType::AmpersandEquals:
|
||||||
case JS::TokenType::Asterisk:
|
case JS::TokenType::Asterisk:
|
||||||
case JS::TokenType::AsteriskAsteriskEquals:
|
case JS::TokenType::DoubleAsteriskEquals:
|
||||||
case JS::TokenType::AsteriskEquals:
|
case JS::TokenType::AsteriskEquals:
|
||||||
case JS::TokenType::Caret:
|
case JS::TokenType::Caret:
|
||||||
case JS::TokenType::CaretEquals:
|
case JS::TokenType::CaretEquals:
|
||||||
|
|
|
@ -850,6 +850,12 @@ Value AssignmentExpression::execute(Interpreter& interpreter) const
|
||||||
return {};
|
return {};
|
||||||
rhs_result = div(interpreter, lhs_result, rhs_result);
|
rhs_result = div(interpreter, lhs_result, rhs_result);
|
||||||
break;
|
break;
|
||||||
|
case AssignmentOp::ExponentiationAssignment:
|
||||||
|
lhs_result = m_lhs->execute(interpreter);
|
||||||
|
if (interpreter.exception())
|
||||||
|
return {};
|
||||||
|
rhs_result = exp(interpreter, lhs_result, rhs_result);
|
||||||
|
break;
|
||||||
case AssignmentOp::BitwiseAndAssignment:
|
case AssignmentOp::BitwiseAndAssignment:
|
||||||
lhs_result = m_lhs->execute(interpreter);
|
lhs_result = m_lhs->execute(interpreter);
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
|
@ -954,6 +960,9 @@ void AssignmentExpression::dump(int indent) const
|
||||||
case AssignmentOp::DivisionAssignment:
|
case AssignmentOp::DivisionAssignment:
|
||||||
op_string = "/=";
|
op_string = "/=";
|
||||||
break;
|
break;
|
||||||
|
case AssignmentOp::ExponentiationAssignment:
|
||||||
|
op_string = "**=";
|
||||||
|
break;
|
||||||
case AssignmentOp::BitwiseAndAssignment:
|
case AssignmentOp::BitwiseAndAssignment:
|
||||||
op_string = "&=";
|
op_string = "&=";
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -604,6 +604,7 @@ enum class AssignmentOp {
|
||||||
SubtractionAssignment,
|
SubtractionAssignment,
|
||||||
MultiplicationAssignment,
|
MultiplicationAssignment,
|
||||||
DivisionAssignment,
|
DivisionAssignment,
|
||||||
|
ExponentiationAssignment,
|
||||||
BitwiseAndAssignment,
|
BitwiseAndAssignment,
|
||||||
BitwiseOrAssignment,
|
BitwiseOrAssignment,
|
||||||
BitwiseXorAssignment,
|
BitwiseXorAssignment,
|
||||||
|
|
|
@ -81,7 +81,7 @@ Lexer::Lexer(StringView source)
|
||||||
if (s_three_char_tokens.is_empty()) {
|
if (s_three_char_tokens.is_empty()) {
|
||||||
s_three_char_tokens.set("===", TokenType::EqualsEqualsEquals);
|
s_three_char_tokens.set("===", TokenType::EqualsEqualsEquals);
|
||||||
s_three_char_tokens.set("!==", TokenType::ExclamationMarkEqualsEquals);
|
s_three_char_tokens.set("!==", TokenType::ExclamationMarkEqualsEquals);
|
||||||
s_three_char_tokens.set("**=", TokenType::AsteriskAsteriskEquals);
|
s_three_char_tokens.set("**=", TokenType::DoubleAsteriskEquals);
|
||||||
s_three_char_tokens.set("<<=", TokenType::ShiftLeftEquals);
|
s_three_char_tokens.set("<<=", TokenType::ShiftLeftEquals);
|
||||||
s_three_char_tokens.set(">>=", TokenType::ShiftRightEquals);
|
s_three_char_tokens.set(">>=", TokenType::ShiftRightEquals);
|
||||||
s_three_char_tokens.set(">>>", TokenType::UnsignedShiftRight);
|
s_three_char_tokens.set(">>>", TokenType::UnsignedShiftRight);
|
||||||
|
|
|
@ -133,7 +133,7 @@ Parser::Parser(Lexer lexer)
|
||||||
g_operator_precedence.set(TokenType::Equals, 3);
|
g_operator_precedence.set(TokenType::Equals, 3);
|
||||||
g_operator_precedence.set(TokenType::PlusEquals, 3);
|
g_operator_precedence.set(TokenType::PlusEquals, 3);
|
||||||
g_operator_precedence.set(TokenType::MinusEquals, 3);
|
g_operator_precedence.set(TokenType::MinusEquals, 3);
|
||||||
g_operator_precedence.set(TokenType::AsteriskAsteriskEquals, 3);
|
g_operator_precedence.set(TokenType::DoubleAsteriskEquals, 3);
|
||||||
g_operator_precedence.set(TokenType::AsteriskEquals, 3);
|
g_operator_precedence.set(TokenType::AsteriskEquals, 3);
|
||||||
g_operator_precedence.set(TokenType::SlashEquals, 3);
|
g_operator_precedence.set(TokenType::SlashEquals, 3);
|
||||||
g_operator_precedence.set(TokenType::PercentEquals, 3);
|
g_operator_precedence.set(TokenType::PercentEquals, 3);
|
||||||
|
@ -637,6 +637,9 @@ NonnullRefPtr<Expression> Parser::parse_secondary_expression(NonnullRefPtr<Expre
|
||||||
case TokenType::DoubleAsterisk:
|
case TokenType::DoubleAsterisk:
|
||||||
consume();
|
consume();
|
||||||
return create_ast_node<BinaryExpression>(BinaryOp::Exponentiation, move(lhs), parse_expression(min_precedence, associativity));
|
return create_ast_node<BinaryExpression>(BinaryOp::Exponentiation, move(lhs), parse_expression(min_precedence, associativity));
|
||||||
|
case TokenType::DoubleAsteriskEquals:
|
||||||
|
consume();
|
||||||
|
return create_ast_node<AssignmentExpression>(AssignmentOp::ExponentiationAssignment, move(lhs), parse_expression(min_precedence, associativity));
|
||||||
case TokenType::GreaterThan:
|
case TokenType::GreaterThan:
|
||||||
consume();
|
consume();
|
||||||
return create_ast_node<BinaryExpression>(BinaryOp::GreaterThan, move(lhs), parse_expression(min_precedence, associativity));
|
return create_ast_node<BinaryExpression>(BinaryOp::GreaterThan, move(lhs), parse_expression(min_precedence, associativity));
|
||||||
|
@ -1192,6 +1195,7 @@ bool Parser::match_secondary_expression() const
|
||||||
|| type == TokenType::SlashEquals
|
|| type == TokenType::SlashEquals
|
||||||
|| type == TokenType::Percent
|
|| type == TokenType::Percent
|
||||||
|| type == TokenType::DoubleAsterisk
|
|| type == TokenType::DoubleAsterisk
|
||||||
|
|| type == TokenType::DoubleAsteriskEquals
|
||||||
|| type == TokenType::Equals
|
|| type == TokenType::Equals
|
||||||
|| type == TokenType::EqualsEqualsEquals
|
|| type == TokenType::EqualsEqualsEquals
|
||||||
|| type == TokenType::ExclamationMarkEqualsEquals
|
|| type == TokenType::ExclamationMarkEqualsEquals
|
||||||
|
|
|
@ -23,6 +23,10 @@ try {
|
||||||
assert((x /= 2) === 3);
|
assert((x /= 2) === 3);
|
||||||
assert(x === 3);
|
assert(x === 3);
|
||||||
|
|
||||||
|
x = 2;
|
||||||
|
assert((x **= 3) === 8);
|
||||||
|
assert(x === 8);
|
||||||
|
|
||||||
x = 3;
|
x = 3;
|
||||||
assert((x &= 2) === 2);
|
assert((x &= 2) === 2);
|
||||||
assert(x === 2);
|
assert(x === 2);
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace JS {
|
||||||
__ENUMERATE_JS_TOKEN(AmpersandEquals) \
|
__ENUMERATE_JS_TOKEN(AmpersandEquals) \
|
||||||
__ENUMERATE_JS_TOKEN(Arrow) \
|
__ENUMERATE_JS_TOKEN(Arrow) \
|
||||||
__ENUMERATE_JS_TOKEN(Asterisk) \
|
__ENUMERATE_JS_TOKEN(Asterisk) \
|
||||||
__ENUMERATE_JS_TOKEN(AsteriskAsteriskEquals) \
|
__ENUMERATE_JS_TOKEN(DoubleAsteriskEquals) \
|
||||||
__ENUMERATE_JS_TOKEN(AsteriskEquals) \
|
__ENUMERATE_JS_TOKEN(AsteriskEquals) \
|
||||||
__ENUMERATE_JS_TOKEN(Await) \
|
__ENUMERATE_JS_TOKEN(Await) \
|
||||||
__ENUMERATE_JS_TOKEN(BoolLiteral) \
|
__ENUMERATE_JS_TOKEN(BoolLiteral) \
|
||||||
|
|
|
@ -567,7 +567,7 @@ int main(int argc, char** argv)
|
||||||
case JS::TokenType::Ampersand:
|
case JS::TokenType::Ampersand:
|
||||||
case JS::TokenType::AmpersandEquals:
|
case JS::TokenType::AmpersandEquals:
|
||||||
case JS::TokenType::Asterisk:
|
case JS::TokenType::Asterisk:
|
||||||
case JS::TokenType::AsteriskAsteriskEquals:
|
case JS::TokenType::DoubleAsteriskEquals:
|
||||||
case JS::TokenType::AsteriskEquals:
|
case JS::TokenType::AsteriskEquals:
|
||||||
case JS::TokenType::Caret:
|
case JS::TokenType::Caret:
|
||||||
case JS::TokenType::CaretEquals:
|
case JS::TokenType::CaretEquals:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue