summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-04-04 21:17:34 +0200
committerAndreas Kling <kling@serenityos.org>2020-04-04 21:17:34 +0200
commit644ff1bbfd53943dde39fbef6cbeca0d607e4c18 (patch)
tree5001b1ccf8942b9de6b20a0427dbc10a297a351c /Libraries
parent9c8363bb5fb1853aedc085e57aafea4b19831223 (diff)
downloadserenity-644ff1bbfd53943dde39fbef6cbeca0d607e4c18.zip
LibJS: Add basic support for modulo (%) in binary expressions
Diffstat (limited to 'Libraries')
-rw-r--r--Libraries/LibJS/AST.cpp5
-rw-r--r--Libraries/LibJS/AST.h1
-rw-r--r--Libraries/LibJS/Parser.cpp4
-rw-r--r--Libraries/LibJS/Runtime/Value.cpp6
-rw-r--r--Libraries/LibJS/Runtime/Value.h1
-rw-r--r--Libraries/LibJS/Tests/modulo-basic.js8
6 files changed, 25 insertions, 0 deletions
diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp
index d3685b7118..ce9bc94267 100644
--- a/Libraries/LibJS/AST.cpp
+++ b/Libraries/LibJS/AST.cpp
@@ -244,6 +244,8 @@ Value BinaryExpression::execute(Interpreter& interpreter) const
return mul(lhs_result, rhs_result);
case BinaryOp::Slash:
return div(lhs_result, rhs_result);
+ case BinaryOp::Modulo:
+ return mod(lhs_result, rhs_result);
case BinaryOp::TypedEquals:
return typed_eq(lhs_result, rhs_result);
case BinaryOp::TypedInequals:
@@ -379,6 +381,9 @@ void BinaryExpression::dump(int indent) const
case BinaryOp::Slash:
op_string = "/";
break;
+ case BinaryOp::Modulo:
+ op_string = "%";
+ break;
case BinaryOp::TypedEquals:
op_string = "===";
break;
diff --git a/Libraries/LibJS/AST.h b/Libraries/LibJS/AST.h
index 2c1d13b386..2d412196e1 100644
--- a/Libraries/LibJS/AST.h
+++ b/Libraries/LibJS/AST.h
@@ -289,6 +289,7 @@ enum class BinaryOp {
Minus,
Asterisk,
Slash,
+ Modulo,
TypedEquals,
TypedInequals,
AbstractEquals,
diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp
index 6541f51fc0..5468432f76 100644
--- a/Libraries/LibJS/Parser.cpp
+++ b/Libraries/LibJS/Parser.cpp
@@ -463,6 +463,9 @@ NonnullRefPtr<Expression> Parser::parse_secondary_expression(NonnullRefPtr<Expre
case TokenType::SlashEquals:
consume();
return create_ast_node<AssignmentExpression>(AssignmentOp::DivisionAssignment, move(lhs), parse_expression(min_precedence, associativity));
+ case TokenType::Percent:
+ consume();
+ return create_ast_node<BinaryExpression>(BinaryOp::Modulo, move(lhs), parse_expression(min_precedence, associativity));
case TokenType::GreaterThan:
consume();
return create_ast_node<BinaryExpression>(BinaryOp::GreaterThan, move(lhs), parse_expression(min_precedence, associativity));
@@ -871,6 +874,7 @@ bool Parser::match_secondary_expression() const
|| type == TokenType::AsteriskEquals
|| type == TokenType::Slash
|| type == TokenType::SlashEquals
+ || type == TokenType::Percent
|| type == TokenType::Equals
|| type == TokenType::EqualsEqualsEquals
|| type == TokenType::ExclamationMarkEqualsEquals
diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp
index d93c463e5b..dc6506b0d1 100644
--- a/Libraries/LibJS/Runtime/Value.cpp
+++ b/Libraries/LibJS/Runtime/Value.cpp
@@ -239,6 +239,12 @@ Value div(Value lhs, Value rhs)
return Value(lhs.to_number().as_double() / rhs.to_number().as_double());
}
+Value mod(Value lhs, Value rhs)
+{
+ // FIXME: It seems like JavaScript should allow modulo for doubles as well(?)
+ return Value(lhs.to_i32() % rhs.to_i32());
+}
+
Value typed_eq(Value lhs, Value rhs)
{
if (rhs.type() != lhs.type())
diff --git a/Libraries/LibJS/Runtime/Value.h b/Libraries/LibJS/Runtime/Value.h
index d83f2cf0bd..df0e742ab9 100644
--- a/Libraries/LibJS/Runtime/Value.h
+++ b/Libraries/LibJS/Runtime/Value.h
@@ -195,6 +195,7 @@ Value add(Value lhs, Value rhs);
Value sub(Value lhs, Value rhs);
Value mul(Value lhs, Value rhs);
Value div(Value lhs, Value rhs);
+Value mod(Value lhs, Value rhs);
Value eq(Value lhs, Value rhs);
Value typed_eq(Value lhs, Value rhs);
Value instance_of(Value lhs, Value rhs);
diff --git a/Libraries/LibJS/Tests/modulo-basic.js b/Libraries/LibJS/Tests/modulo-basic.js
new file mode 100644
index 0000000000..78410ee6c5
--- /dev/null
+++ b/Libraries/LibJS/Tests/modulo-basic.js
@@ -0,0 +1,8 @@
+function assert(x) { if (!x) throw 1; }
+
+try {
+ assert(10 % 3 === 1);
+ console.log("PASS");
+} catch (e) {
+ console.log("FAIL: " + e);
+}