summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2020-05-17 15:12:34 +0100
committerAndreas Kling <kling@serenityos.org>2020-05-17 16:21:33 +0200
commit6f6b089aa01ad88041f3da8120b99c03ccd9d1d4 (patch)
tree3382bc68630a89ee87d13f1c5b8c04c1b61d13de
parentcc42d75209424bc6fcaecbf82b95d980863de7f1 (diff)
downloadserenity-6f6b089aa01ad88041f3da8120b99c03ccd9d1d4.zip
LibJS: Add parseFloat()
-rw-r--r--Libraries/LibJS/Runtime/GlobalObject.cpp15
-rw-r--r--Libraries/LibJS/Runtime/GlobalObject.h1
-rw-r--r--Libraries/LibJS/Tests/parseFloat.js71
3 files changed, 87 insertions, 0 deletions
diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp
index 4b9497efd1..e81179168b 100644
--- a/Libraries/LibJS/Runtime/GlobalObject.cpp
+++ b/Libraries/LibJS/Runtime/GlobalObject.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2020, Linus Groh <mail@linusgroh.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -82,6 +83,7 @@ void GlobalObject::initialize()
put_native_function("gc", gc, 0, attr);
put_native_function("isNaN", is_nan, 1, attr);
put_native_function("isFinite", is_finite, 1, attr);
+ put_native_function("parseFloat", parse_float, 1, attr);
put("NaN", js_nan(), 0);
put("Infinity", js_infinity(), 0);
@@ -140,4 +142,17 @@ Value GlobalObject::is_finite(Interpreter& interpreter)
return Value(interpreter.argument(0).to_number().is_finite_number());
}
+Value GlobalObject::parse_float(Interpreter& interpreter)
+{
+ auto string = interpreter.argument(0).to_string(interpreter);
+ if (interpreter.exception())
+ return {};
+ for (size_t length = string.length(); length > 0; --length) {
+ auto number = Value(js_string(interpreter, string.substring(0, length))).to_number();
+ if (!number.is_nan())
+ return number;
+ }
+ return js_nan();
+}
+
}
diff --git a/Libraries/LibJS/Runtime/GlobalObject.h b/Libraries/LibJS/Runtime/GlobalObject.h
index 214a447a25..42a99b37fe 100644
--- a/Libraries/LibJS/Runtime/GlobalObject.h
+++ b/Libraries/LibJS/Runtime/GlobalObject.h
@@ -58,6 +58,7 @@ private:
static Value gc(Interpreter&);
static Value is_nan(Interpreter&);
static Value is_finite(Interpreter&);
+ static Value parse_float(Interpreter&);
Shape* m_empty_object_shape { nullptr };
diff --git a/Libraries/LibJS/Tests/parseFloat.js b/Libraries/LibJS/Tests/parseFloat.js
new file mode 100644
index 0000000000..89045b2900
--- /dev/null
+++ b/Libraries/LibJS/Tests/parseFloat.js
@@ -0,0 +1,71 @@
+load("test-common.js");
+
+try {
+ const NUMBER_TEST_CASES = [
+ [0, 0],
+ [1, 1],
+ [.23, 0.23],
+ [1.23, 1.23],
+ [0.0123E+2, 1.23],
+ [1.23e4, 12300],
+ [Infinity, Infinity]
+ ];
+
+ NUMBER_TEST_CASES.forEach(test => {
+ const value = test[0];
+ const result = test[1];
+ assert(parseFloat(value) === result);
+ assert(parseFloat(+value) === result);
+ assert(parseFloat(-value) === -result);
+ });
+
+ const STRING_TEST_CASES = [
+ ["0", 0],
+ ["1", 1],
+ [".23", 0.23],
+ ["1.23", 1.23],
+ ["0.0123E+2", 1.23],
+ ["1.23e4", 12300],
+ ["Infinity", Infinity]
+ ];
+
+ STRING_TEST_CASES.forEach(test => {
+ const value = test[0];
+ const result = test[1];
+ assert(parseFloat(value) === result);
+ assert(parseFloat(`+${value}`) === result);
+ assert(parseFloat(`-${value}`) === -result);
+ assert(parseFloat(`${value}foo`) === result);
+ assert(parseFloat(`+${value}foo`) === result);
+ assert(parseFloat(`-${value}foo`) === -result);
+ assert(parseFloat(` \n \t ${value} \v foo `) === result);
+ assert(parseFloat(` \r -${value} \f \n\n foo `) === -result);
+ assert(parseFloat({ toString: () => value }) === result);
+ });
+
+ const NAN_TEST_CASES = [
+ "",
+ [],
+ [],
+ true,
+ false,
+ null,
+ undefined,
+ NaN,
+ "foo123",
+ "foo+123",
+ "fooInfinity",
+ "foo+Infinity"
+ ];
+
+ assert(isNaN(parseFloat()));
+ assert(isNaN(parseFloat("", 123, Infinity)));
+
+ NAN_TEST_CASES.forEach(value => {
+ assert(isNaN(parseFloat(value)));
+ });
+
+ console.log("PASS");
+} catch (e) {
+ console.log("FAIL: " + e)
+}