mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 11:36:10 +00:00
LibJS: Implement bitwise assignment operators (&=, |=, ^=)
This commit is contained in:
parent
8e4301dea6
commit
3e754a15d4
Notes:
sideshowbarker
2024-07-19 06:58:00 +09:00
Author: https://github.com/linusg Commit: https://github.com/SerenityOS/serenity/commit/3e754a15d48 Pull-request: https://github.com/SerenityOS/serenity/pull/2105
8 changed files with 62 additions and 2 deletions
|
@ -50,7 +50,6 @@ static TextStyle style_for_token_type(Gfx::Palette palette, JS::TokenType type)
|
|||
return { palette.syntax_string() };
|
||||
case JS::TokenType::BracketClose:
|
||||
case JS::TokenType::BracketOpen:
|
||||
case JS::TokenType::Caret:
|
||||
case JS::TokenType::Comma:
|
||||
case JS::TokenType::CurlyClose:
|
||||
case JS::TokenType::CurlyOpen:
|
||||
|
@ -65,6 +64,8 @@ static TextStyle style_for_token_type(Gfx::Palette palette, JS::TokenType type)
|
|||
case JS::TokenType::Asterisk:
|
||||
case JS::TokenType::AsteriskAsteriskEquals:
|
||||
case JS::TokenType::AsteriskEquals:
|
||||
case JS::TokenType::Caret:
|
||||
case JS::TokenType::CaretEquals:
|
||||
case JS::TokenType::DoubleAmpersand:
|
||||
case JS::TokenType::DoubleAsterisk:
|
||||
case JS::TokenType::DoublePipe:
|
||||
|
|
|
@ -850,6 +850,24 @@ Value AssignmentExpression::execute(Interpreter& interpreter) const
|
|||
return {};
|
||||
rhs_result = div(interpreter, lhs_result, rhs_result);
|
||||
break;
|
||||
case AssignmentOp::BitwiseAndAssignment:
|
||||
lhs_result = m_lhs->execute(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
rhs_result = bitwise_and(interpreter, lhs_result, rhs_result);
|
||||
break;
|
||||
case AssignmentOp::BitwiseOrAssignment:
|
||||
lhs_result = m_lhs->execute(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
rhs_result = bitwise_or(interpreter, lhs_result, rhs_result);
|
||||
break;
|
||||
case AssignmentOp::BitwiseXorAssignment:
|
||||
lhs_result = m_lhs->execute(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
rhs_result = bitwise_xor(interpreter, lhs_result, rhs_result);
|
||||
break;
|
||||
case AssignmentOp::LeftShiftAssignment:
|
||||
lhs_result = m_lhs->execute(interpreter);
|
||||
if (interpreter.exception())
|
||||
|
@ -936,6 +954,15 @@ void AssignmentExpression::dump(int indent) const
|
|||
case AssignmentOp::DivisionAssignment:
|
||||
op_string = "/=";
|
||||
break;
|
||||
case AssignmentOp::BitwiseAndAssignment:
|
||||
op_string = "&=";
|
||||
break;
|
||||
case AssignmentOp::BitwiseOrAssignment:
|
||||
op_string = "|=";
|
||||
break;
|
||||
case AssignmentOp::BitwiseXorAssignment:
|
||||
op_string = "^=";
|
||||
break;
|
||||
case AssignmentOp::LeftShiftAssignment:
|
||||
op_string = "<<=";
|
||||
break;
|
||||
|
|
|
@ -604,6 +604,9 @@ enum class AssignmentOp {
|
|||
SubtractionAssignment,
|
||||
MultiplicationAssignment,
|
||||
DivisionAssignment,
|
||||
BitwiseAndAssignment,
|
||||
BitwiseOrAssignment,
|
||||
BitwiseXorAssignment,
|
||||
LeftShiftAssignment,
|
||||
RightShiftAssignment,
|
||||
UnsignedRightShiftAssignment,
|
||||
|
|
|
@ -97,6 +97,7 @@ Lexer::Lexer(StringView source)
|
|||
s_two_char_tokens.set("%=", TokenType::PercentEquals);
|
||||
s_two_char_tokens.set("&=", TokenType::AmpersandEquals);
|
||||
s_two_char_tokens.set("|=", TokenType::PipeEquals);
|
||||
s_two_char_tokens.set("^=", TokenType::CaretEquals);
|
||||
s_two_char_tokens.set("&&", TokenType::DoubleAmpersand);
|
||||
s_two_char_tokens.set("||", TokenType::DoublePipe);
|
||||
s_two_char_tokens.set("??", TokenType::DoubleQuestionMark);
|
||||
|
|
|
@ -140,7 +140,9 @@ Parser::Parser(Lexer lexer)
|
|||
g_operator_precedence.set(TokenType::ShiftLeftEquals, 3);
|
||||
g_operator_precedence.set(TokenType::ShiftRightEquals, 3);
|
||||
g_operator_precedence.set(TokenType::UnsignedShiftRightEquals, 3);
|
||||
g_operator_precedence.set(TokenType::AmpersandEquals, 3);
|
||||
g_operator_precedence.set(TokenType::PipeEquals, 3);
|
||||
g_operator_precedence.set(TokenType::CaretEquals, 3);
|
||||
|
||||
g_operator_precedence.set(TokenType::Yield, 2);
|
||||
|
||||
|
@ -668,12 +670,21 @@ NonnullRefPtr<Expression> Parser::parse_secondary_expression(NonnullRefPtr<Expre
|
|||
case TokenType::Ampersand:
|
||||
consume();
|
||||
return create_ast_node<BinaryExpression>(BinaryOp::BitwiseAnd, move(lhs), parse_expression(min_precedence, associativity));
|
||||
case TokenType::AmpersandEquals:
|
||||
consume();
|
||||
return create_ast_node<AssignmentExpression>(AssignmentOp::BitwiseAndAssignment, move(lhs), parse_expression(min_precedence, associativity));
|
||||
case TokenType::Pipe:
|
||||
consume();
|
||||
return create_ast_node<BinaryExpression>(BinaryOp::BitwiseOr, move(lhs), parse_expression(min_precedence, associativity));
|
||||
case TokenType::PipeEquals:
|
||||
consume();
|
||||
return create_ast_node<AssignmentExpression>(AssignmentOp::BitwiseOrAssignment, move(lhs), parse_expression(min_precedence, associativity));
|
||||
case TokenType::Caret:
|
||||
consume();
|
||||
return create_ast_node<BinaryExpression>(BinaryOp::BitwiseXor, move(lhs), parse_expression(min_precedence, associativity));
|
||||
case TokenType::CaretEquals:
|
||||
consume();
|
||||
return create_ast_node<AssignmentExpression>(AssignmentOp::BitwiseXorAssignment, move(lhs), parse_expression(min_precedence, associativity));
|
||||
case TokenType::ShiftLeft:
|
||||
consume();
|
||||
return create_ast_node<BinaryExpression>(BinaryOp::LeftShift, move(lhs), parse_expression(min_precedence, associativity));
|
||||
|
@ -1199,8 +1210,11 @@ bool Parser::match_secondary_expression() const
|
|||
|| type == TokenType::Instanceof
|
||||
|| type == TokenType::QuestionMark
|
||||
|| type == TokenType::Ampersand
|
||||
|| type == TokenType::AmpersandEquals
|
||||
|| type == TokenType::Pipe
|
||||
|| type == TokenType::PipeEquals
|
||||
|| type == TokenType::Caret
|
||||
|| type == TokenType::CaretEquals
|
||||
|| type == TokenType::ShiftLeft
|
||||
|| type == TokenType::ShiftLeftEquals
|
||||
|| type == TokenType::ShiftRight
|
||||
|
|
|
@ -23,6 +23,18 @@ try {
|
|||
assert((x /= 2) === 3);
|
||||
assert(x === 3);
|
||||
|
||||
x = 3;
|
||||
assert((x &= 2) === 2);
|
||||
assert(x === 2);
|
||||
|
||||
x = 3;
|
||||
assert((x |= 4) === 7);
|
||||
assert(x === 7);
|
||||
|
||||
x = 6;
|
||||
assert((x ^= 2) === 4);
|
||||
assert(x === 4);
|
||||
|
||||
x = 2;
|
||||
assert((x <<= 2) === 8);
|
||||
assert(x === 8);
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace JS {
|
|||
__ENUMERATE_JS_TOKEN(BracketOpen) \
|
||||
__ENUMERATE_JS_TOKEN(Break) \
|
||||
__ENUMERATE_JS_TOKEN(Caret) \
|
||||
__ENUMERATE_JS_TOKEN(CaretEquals) \
|
||||
__ENUMERATE_JS_TOKEN(Case) \
|
||||
__ENUMERATE_JS_TOKEN(Catch) \
|
||||
__ENUMERATE_JS_TOKEN(Class) \
|
||||
|
|
|
@ -556,7 +556,6 @@ int main(int argc, char** argv)
|
|||
break;
|
||||
case JS::TokenType::BracketClose:
|
||||
case JS::TokenType::BracketOpen:
|
||||
case JS::TokenType::Caret:
|
||||
case JS::TokenType::Comma:
|
||||
case JS::TokenType::CurlyClose:
|
||||
case JS::TokenType::CurlyOpen:
|
||||
|
@ -570,6 +569,8 @@ int main(int argc, char** argv)
|
|||
case JS::TokenType::Asterisk:
|
||||
case JS::TokenType::AsteriskAsteriskEquals:
|
||||
case JS::TokenType::AsteriskEquals:
|
||||
case JS::TokenType::Caret:
|
||||
case JS::TokenType::CaretEquals:
|
||||
case JS::TokenType::DoubleAmpersand:
|
||||
case JS::TokenType::DoubleAsterisk:
|
||||
case JS::TokenType::DoublePipe:
|
||||
|
|
Loading…
Add table
Reference in a new issue