diff --git a/Libraries/LibJS/Runtime/MathObject.cpp b/Libraries/LibJS/Runtime/MathObject.cpp index 96218036d7..e596165659 100644 --- a/Libraries/LibJS/Runtime/MathObject.cpp +++ b/Libraries/LibJS/Runtime/MathObject.cpp @@ -26,12 +26,15 @@ #include #include +#include +#include #include namespace JS { MathObject::MathObject() { + put_native_function("abs", abs); put_native_function("random", random); } @@ -39,6 +42,28 @@ MathObject::~MathObject() { } +Value MathObject::abs(Interpreter& interpreter) +{ + if (interpreter.call_frame().arguments.is_empty()) + return js_nan(); + + auto argument = interpreter.call_frame().arguments[0]; + + if (argument.is_array()) { + auto& array = *static_cast(argument.as_object()); + if (array.length() == 0) + return Value(0); + if (array.length() > 1) + return js_nan(); + argument = array.elements()[0]; + } + + auto number = argument.to_number(); + if (number.is_nan()) + return js_nan(); + return Value(number.as_double() >= 0 ? number.as_double() : -number.as_double()); +} + Value MathObject::random(Interpreter&) { #ifdef __serenity__ diff --git a/Libraries/LibJS/Runtime/MathObject.h b/Libraries/LibJS/Runtime/MathObject.h index 5d5e079321..1953eeb3a2 100644 --- a/Libraries/LibJS/Runtime/MathObject.h +++ b/Libraries/LibJS/Runtime/MathObject.h @@ -38,6 +38,7 @@ public: private: virtual const char* class_name() const override { return "MathObject"; } + static Value abs(Interpreter&); static Value random(Interpreter&); }; diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp index 196a51a365..240d828696 100644 --- a/Libraries/LibJS/Runtime/Value.cpp +++ b/Libraries/LibJS/Runtime/Value.cpp @@ -114,9 +114,12 @@ Value Value::to_number() const case Type::Null: return Value(0); case Type::String: { + auto& string = as_string()->string(); + if (string.is_empty()) + return Value(0); bool ok; //FIXME: Parse in a better way - auto parsed_int = as_string()->string().to_int(ok); + auto parsed_int = string.to_int(ok); if (ok) return Value(parsed_int); diff --git a/Libraries/LibJS/Tests/Math.abs.js b/Libraries/LibJS/Tests/Math.abs.js new file mode 100644 index 0000000000..27ba82b35e --- /dev/null +++ b/Libraries/LibJS/Tests/Math.abs.js @@ -0,0 +1,16 @@ +function assert(x) { if (!x) throw 1; } + +try { + assert(Math.abs('-1') === 1); + assert(Math.abs(0 - 2) === 2); + assert(Math.abs(null) === 0); + assert(Math.abs('') === 0); + assert(Math.abs([]) === 0); + assert(Math.abs([2]) === 2); + assert(isNaN(Math.abs([1, 2]))); + assert(isNaN(Math.abs({}))); + assert(isNaN(Math.abs('string'))); + assert(isNaN(Math.abs())); + console.log("PASS"); +} catch { +}