mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 17:10:23 +00:00
LibJS: Implement unary plus / minus
This commit is contained in:
parent
5e6e1fd482
commit
a62230770b
Notes:
sideshowbarker
2024-07-19 07:59:16 +09:00
Author: https://github.com/linusg Commit: https://github.com/SerenityOS/serenity/commit/a62230770ba Pull-request: https://github.com/SerenityOS/serenity/pull/1587
9 changed files with 73 additions and 25 deletions
|
@ -303,6 +303,10 @@ Value UnaryExpression::execute(Interpreter& interpreter) const
|
|||
return bitwise_not(lhs_result);
|
||||
case UnaryOp::Not:
|
||||
return Value(!lhs_result.to_boolean());
|
||||
case UnaryOp::Plus:
|
||||
return unary_plus(lhs_result);
|
||||
case UnaryOp::Minus:
|
||||
return unary_minus(lhs_result);
|
||||
case UnaryOp::Typeof:
|
||||
switch (lhs_result.type()) {
|
||||
case Value::Type::Undefined:
|
||||
|
@ -442,6 +446,12 @@ void UnaryExpression::dump(int indent) const
|
|||
case UnaryOp::Not:
|
||||
op_string = "!";
|
||||
break;
|
||||
case UnaryOp::Plus:
|
||||
op_string = "+";
|
||||
break;
|
||||
case UnaryOp::Minus:
|
||||
op_string = "-";
|
||||
break;
|
||||
case UnaryOp::Typeof:
|
||||
op_string = "typeof ";
|
||||
break;
|
||||
|
|
|
@ -353,6 +353,8 @@ private:
|
|||
enum class UnaryOp {
|
||||
BitwiseNot,
|
||||
Not,
|
||||
Plus,
|
||||
Minus,
|
||||
Typeof,
|
||||
};
|
||||
|
||||
|
|
|
@ -365,6 +365,12 @@ NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression()
|
|||
case TokenType::Tilde:
|
||||
consume();
|
||||
return create_ast_node<UnaryExpression>(UnaryOp::BitwiseNot, parse_expression(precedence, associativity));
|
||||
case TokenType::Plus:
|
||||
consume();
|
||||
return create_ast_node<UnaryExpression>(UnaryOp::Plus, parse_expression(precedence, associativity));
|
||||
case TokenType::Minus:
|
||||
consume();
|
||||
return create_ast_node<UnaryExpression>(UnaryOp::Minus, parse_expression(precedence, associativity));
|
||||
case TokenType::Typeof:
|
||||
consume();
|
||||
return create_ast_node<UnaryExpression>(UnaryOp::Typeof, parse_expression(precedence, associativity));
|
||||
|
@ -833,6 +839,8 @@ bool Parser::match_unary_prefixed_expression() const
|
|||
|| type == TokenType::MinusMinus
|
||||
|| type == TokenType::ExclamationMark
|
||||
|| type == TokenType::Tilde
|
||||
|| type == TokenType::Plus
|
||||
|| type == TokenType::Minus
|
||||
|| type == TokenType::Typeof;
|
||||
}
|
||||
|
||||
|
|
|
@ -191,6 +191,18 @@ Value bitwise_not(Value lhs)
|
|||
return Value(~(i32)lhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value unary_plus(Value lhs)
|
||||
{
|
||||
return lhs.to_number();
|
||||
}
|
||||
|
||||
Value unary_minus(Value lhs)
|
||||
{
|
||||
if (lhs.to_number().is_nan())
|
||||
return js_nan();
|
||||
return Value(-lhs.to_number().as_double());
|
||||
}
|
||||
|
||||
Value left_shift(Value lhs, Value rhs)
|
||||
{
|
||||
return Value((i32)lhs.to_number().as_double() << (i32)rhs.to_number().as_double());
|
||||
|
|
|
@ -181,6 +181,8 @@ Value bitwise_and(Value lhs, Value rhs);
|
|||
Value bitwise_or(Value lhs, Value rhs);
|
||||
Value bitwise_xor(Value lhs, Value rhs);
|
||||
Value bitwise_not(Value);
|
||||
Value unary_plus(Value);
|
||||
Value unary_minus(Value);
|
||||
Value left_shift(Value lhs, Value rhs);
|
||||
Value right_shift(Value lhs, Value rhs);
|
||||
Value add(Value lhs, Value rhs);
|
||||
|
|
|
@ -2,7 +2,7 @@ function assert(x) { if (!x) throw 1; }
|
|||
|
||||
try {
|
||||
assert(Math.abs('-1') === 1);
|
||||
assert(Math.abs(0 - 2) === 2);
|
||||
assert(Math.abs(-2) === 2);
|
||||
assert(Math.abs(null) === 0);
|
||||
assert(Math.abs('') === 0);
|
||||
assert(Math.abs([]) === 0);
|
||||
|
|
|
@ -22,7 +22,7 @@ try {
|
|||
assert(s.startsWith("foo", false) === true);
|
||||
assert(s.startsWith("foo", true) === false);
|
||||
assert(s.startsWith("foo", "foo") === true);
|
||||
assert(s.startsWith("foo", 0 - 1) === true);
|
||||
assert(s.startsWith("foo", -1) === true);
|
||||
assert(s.startsWith("foo", 42) === false);
|
||||
assert(s.startsWith("bar", 3) === true);
|
||||
assert(s.startsWith("bar", "3") === true);
|
||||
|
@ -31,7 +31,7 @@ try {
|
|||
assert(s.startsWith("") === true);
|
||||
assert(s.startsWith("", 0) === true);
|
||||
assert(s.startsWith("", 1) === true);
|
||||
assert(s.startsWith("", 0 - 1) === true);
|
||||
assert(s.startsWith("", -1) === true);
|
||||
assert(s.startsWith("", 42) === true);
|
||||
|
||||
console.log("PASS");
|
||||
|
|
|
@ -8,6 +8,8 @@ try {
|
|||
assert(!o.a === false);
|
||||
assert(!o.a === !(o.a));
|
||||
assert(~o.a === ~(o.a));
|
||||
assert(+o.a === +(o.a));
|
||||
assert(-o.a === -(o.a));
|
||||
|
||||
assert((typeof "x" === "string") === true);
|
||||
assert(!(typeof "x" === "string") === false);
|
||||
|
|
|
@ -1,31 +1,43 @@
|
|||
function assert(x) { if (!x) throw 1; }
|
||||
|
||||
// FIXME: Just "+x" doesn't parse currently,
|
||||
// so we use "x - 0", which is effectively the same.
|
||||
// "0 + x" would _not_ work in all cases.
|
||||
function n(x) { return x - 0; }
|
||||
|
||||
try {
|
||||
assert(n(false) === 0);
|
||||
assert(n(true) === 1);
|
||||
assert(n(null) === 0);
|
||||
assert(n([]) === 0);
|
||||
assert(n([[[[[]]]]]) === 0);
|
||||
assert(n([[[[[42]]]]]) === 42);
|
||||
assert(n("") === 0);
|
||||
assert(n("42") === 42);
|
||||
assert(n(42) === 42);
|
||||
assert(+false === 0);
|
||||
assert(-false === 0);
|
||||
assert(+true === 1);
|
||||
assert(-true === -1);
|
||||
assert(+null === 0);
|
||||
assert(-null === 0);
|
||||
assert(+[] === 0);
|
||||
assert(-[] === 0);
|
||||
assert(+[[[[[]]]]] === 0);
|
||||
assert(-[[[[[]]]]] === 0);
|
||||
assert(+[[[[[42]]]]] === 42);
|
||||
assert(-[[[[[42]]]]] === -42);
|
||||
assert(+"" === 0);
|
||||
assert(-"" === 0);
|
||||
assert(+"42" === 42);
|
||||
assert(-"42" === -42);
|
||||
assert(+42 === 42);
|
||||
assert(-42 === -42);
|
||||
// FIXME: returns NaN
|
||||
// assert(n("1.23") === 1.23)
|
||||
// assert(+"1.23" === 1.23)
|
||||
// assert(-"1.23" === -1.23)
|
||||
// FIXME: chokes on ASSERT
|
||||
// assert(n(1.23) === 1.23);
|
||||
// assert(+1.23 === 1.23);
|
||||
// assert(-1.23 === -1.23);
|
||||
|
||||
assert(isNaN(n(undefined)));
|
||||
assert(isNaN(n({})));
|
||||
assert(isNaN(n({a: 1})));
|
||||
assert(isNaN(n([1, 2, 3])));
|
||||
assert(isNaN(n([[[["foo"]]]])));
|
||||
assert(isNaN(n("foo")));
|
||||
assert(isNaN(+undefined));
|
||||
assert(isNaN(-undefined));
|
||||
assert(isNaN(+{}));
|
||||
assert(isNaN(-{}));
|
||||
assert(isNaN(+{a: 1}));
|
||||
assert(isNaN(-{a: 1}));
|
||||
assert(isNaN(+[1, 2, 3]));
|
||||
assert(isNaN(-[1, 2, 3]));
|
||||
assert(isNaN(+[[[["foo"]]]]));
|
||||
assert(isNaN(-[[[["foo"]]]]));
|
||||
assert(isNaN(+"foo"));
|
||||
assert(isNaN(-"foo"));
|
||||
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
|
|
Loading…
Reference in a new issue