mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Implement parseFloat()
JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai.u-szeged@partner.samsung.com
This commit is contained in:
parent
35840a4b6d
commit
7508b803cf
@ -264,10 +264,165 @@ ecma_builtin_global_object_parse_int (ecma_value_t this_arg __attr_unused___, /*
|
||||
* Returned value must be freed with ecma_free_completion_value.
|
||||
*/
|
||||
static ecma_completion_value_t
|
||||
ecma_builtin_global_object_parse_float (ecma_value_t this_arg, /**< this argument */
|
||||
ecma_builtin_global_object_parse_float (ecma_value_t this_arg __attr_unused___, /**< this argument */
|
||||
ecma_value_t string) /**< routine's first argument */
|
||||
{
|
||||
ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, string);
|
||||
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
|
||||
|
||||
/* 1. */
|
||||
ECMA_TRY_CATCH (string_var, ecma_op_to_string (string), ret_value);
|
||||
|
||||
ecma_string_t *number_str_p = ecma_get_string_from_value (string_var);
|
||||
int32_t string_len = ecma_string_get_length (number_str_p);
|
||||
|
||||
MEM_DEFINE_LOCAL_ARRAY (zt_string_buff, string_len + 1, ecma_char_t);
|
||||
|
||||
size_t string_buf_size = (size_t) (string_len + 1) * sizeof (ecma_char_t);
|
||||
ssize_t bytes_copied = ecma_string_to_zt_string (number_str_p,
|
||||
zt_string_buff,
|
||||
(ssize_t) string_buf_size);
|
||||
JERRY_ASSERT (bytes_copied > 0);
|
||||
|
||||
/* 2. Find first non whitespace char. */
|
||||
int32_t start = 0;
|
||||
for (int i = 0; i < string_len; i++)
|
||||
{
|
||||
if (!isspace (zt_string_buff[i]))
|
||||
{
|
||||
start = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool sign = false;
|
||||
|
||||
/* Check if sign is present. */
|
||||
if (zt_string_buff[start] == '-')
|
||||
{
|
||||
sign = true;
|
||||
start++;
|
||||
}
|
||||
else if (zt_string_buff[start] == '+')
|
||||
{
|
||||
start++;
|
||||
}
|
||||
|
||||
ecma_number_t *ret_num_p = ecma_alloc_number ();
|
||||
|
||||
/* Check if string is equal to "Infinity". */
|
||||
const ecma_char_t *infinity_zt_str_p = ecma_get_magic_string_zt (ECMA_MAGIC_STRING_INFINITY_UL);
|
||||
|
||||
for (int i = 0; infinity_zt_str_p[i] == zt_string_buff[start + i]; i++)
|
||||
{
|
||||
if (infinity_zt_str_p[i + 1] == 0)
|
||||
{
|
||||
*ret_num_p = ecma_number_make_infinity (sign);
|
||||
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ecma_is_completion_value_empty (ret_value))
|
||||
{
|
||||
int32_t current = start;
|
||||
int32_t end = string_len;
|
||||
bool has_whole_part = false;
|
||||
bool has_fraction_part = false;
|
||||
|
||||
if (isdigit (zt_string_buff[current]))
|
||||
{
|
||||
has_whole_part = true;
|
||||
|
||||
/* Check digits of whole part. */
|
||||
for (int i = current; i < string_len; i++, current++)
|
||||
{
|
||||
if (!isdigit (zt_string_buff[current]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end = current;
|
||||
|
||||
/* Check decimal point. */
|
||||
if (zt_string_buff[current] == '.')
|
||||
{
|
||||
current++;
|
||||
|
||||
if (isdigit (zt_string_buff[current]))
|
||||
{
|
||||
has_fraction_part = true;
|
||||
|
||||
/* Check digits of fractional part. */
|
||||
for (int i = current; i < string_len; i++, current++)
|
||||
{
|
||||
if (!isdigit (zt_string_buff[current]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end = current;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check exponent. */
|
||||
if ((zt_string_buff[current] == 'e' || zt_string_buff[current] == 'E')
|
||||
&& (has_whole_part || has_fraction_part))
|
||||
{
|
||||
current++;
|
||||
|
||||
/* Check sign of exponent. */
|
||||
if (zt_string_buff[current] == '-' || zt_string_buff[current] == '+')
|
||||
{
|
||||
current++;
|
||||
}
|
||||
|
||||
if (isdigit (zt_string_buff[current]))
|
||||
{
|
||||
|
||||
/* Check digits of exponent part. */
|
||||
for (int i = current; i < string_len; i++, current++)
|
||||
{
|
||||
if (!isdigit (zt_string_buff[current]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end = current;
|
||||
}
|
||||
}
|
||||
|
||||
if (start == end)
|
||||
{
|
||||
*ret_num_p = ecma_number_make_nan ();
|
||||
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (end < string_len)
|
||||
{
|
||||
/* 4. End of valid number, terminate the string. */
|
||||
zt_string_buff[end] = '\0';
|
||||
}
|
||||
|
||||
/* 5. */
|
||||
*ret_num_p = ecma_zt_string_to_number (zt_string_buff + start);
|
||||
|
||||
if (sign)
|
||||
{
|
||||
*ret_num_p *= -1;
|
||||
}
|
||||
|
||||
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
|
||||
}
|
||||
}
|
||||
|
||||
MEM_FINALIZE_LOCAL_ARRAY (zt_string_buff);
|
||||
ECMA_FINALIZE (string_var);
|
||||
return ret_value;
|
||||
} /* ecma_builtin_global_object_parse_float */
|
||||
|
||||
/**
|
||||
|
||||
67
tests/jerry/global-parsefloat.js
Normal file
67
tests/jerry/global-parsefloat.js
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright 2015 Samsung Electronics Co., Ltd.
|
||||
// Copyright 2015 University of Szeged.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
assert(parseFloat("1") === 1);
|
||||
assert(parseFloat("+1") === 1);
|
||||
assert(parseFloat("-1") === -1);
|
||||
assert(parseFloat("1.2") === 1.2);
|
||||
assert(parseFloat("+1.2") === 1.2);
|
||||
assert(parseFloat("-1.2") === -1.2);
|
||||
assert(parseFloat("1.2e3") === 1200);
|
||||
assert(parseFloat("+1.2e3") === 1200);
|
||||
assert(parseFloat("-1.2e3") === -1200);
|
||||
assert(parseFloat(" \n\t 1.2e3") === 1200);
|
||||
assert(parseFloat(".2e3") === 200);
|
||||
assert(parseFloat("1.e3") === 1000);
|
||||
assert(parseFloat("1.2e") === 1.2);
|
||||
assert(parseFloat("1.e") === 1);
|
||||
assert(parseFloat("1.e3") === 1000);
|
||||
assert(parseFloat("1e3") === 1000);
|
||||
assert(parseFloat("1e") === 1);
|
||||
assert(parseFloat("1.2e3foo") === 1200);
|
||||
assert(isNaN(parseFloat("foo1.2e3foo")));
|
||||
assert(parseFloat("Infinity") === Infinity);
|
||||
assert(parseFloat("-Infinity") === -Infinity);
|
||||
assert(parseFloat("Infinityfoo") === Infinity);
|
||||
assert(parseFloat("-Infinityfoo") === -Infinity);
|
||||
assert(isNaN(parseFloat("")));
|
||||
assert(isNaN(parseFloat(".")));
|
||||
assert(isNaN(parseFloat("e3")));
|
||||
assert(isNaN(parseFloat(".e3")));
|
||||
assert(parseFloat("0") === 0);
|
||||
assert(parseFloat(".0") === 0);
|
||||
assert(parseFloat("0.e3") === 0);
|
||||
assert(parseFloat("0.0e3") === 0);
|
||||
|
||||
var obj = new Object();
|
||||
var arr = [3,4,5];
|
||||
var num = 7;
|
||||
var bool = true;
|
||||
var undef;
|
||||
|
||||
assert(isNaN(parseFloat(obj)));
|
||||
assert(parseFloat(arr) === 3);
|
||||
assert(parseFloat(num) === 7);
|
||||
assert(isNaN(parseFloat(bool)));
|
||||
assert(isNaN(parseFloat(undef)));
|
||||
|
||||
var obj = { toString : function () { throw new ReferenceError("foo") } };
|
||||
try {
|
||||
parseFloat(obj);
|
||||
assert(false);
|
||||
} catch (e) {
|
||||
assert(e instanceof ReferenceError);
|
||||
assert(e.message === "foo");
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user