Implement parseFloat()

JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai.u-szeged@partner.samsung.com
This commit is contained in:
Dániel Bátyai
2015-06-15 14:19:37 +02:00
parent 35840a4b6d
commit 7508b803cf
2 changed files with 224 additions and 2 deletions
@@ -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 */
/**