Implement BigInt literal parsing in the parser. (#4089)

Support octal literals for BigInts.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2020-08-04 14:16:38 +02:00
committed by GitHub
parent be9dbeffdb
commit b5a96c9eca
16 changed files with 481 additions and 215 deletions
+19 -10
View File
@@ -36,17 +36,16 @@ ecma_bigint_raise_memory_error (void)
/**
* Parse a string and create a BigInt value
*
* @return ecma BigInt value or ECMA_VALUE_ERROR
* @return ecma BigInt value or a special value allowed by the option flags
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_bigint_parse_string (const lit_utf8_byte_t *string_p, /**< string represenation of the BigInt */
lit_utf8_size_t size, /**< string size */
bool throw_syntax_error) /**< true, if syntax errors should be thrown
* otherwise ECMA_VALUE_FALSE is returned on syntax error */
uint32_t options) /**< ecma_bigint_parse_string_options_t option bits */
{
ecma_bigint_digit_t radix = 10;
uint32_t sign = 0;
uint32_t sign = (options & ECMA_BIGINT_PARSE_SET_NEGATIVE) ? ECMA_BIGINT_SIGN : 0;
if (size >= 3 && string_p[0] == LIT_CHAR_0)
{
@@ -56,6 +55,12 @@ ecma_bigint_parse_string (const lit_utf8_byte_t *string_p, /**< string represena
string_p += 2;
size -= 2;
}
else if (string_p[1] == LIT_CHAR_LOWERCASE_O || string_p[1] == LIT_CHAR_UPPERCASE_O)
{
radix = 8;
string_p += 2;
size -= 2;
}
else if (string_p[1] == LIT_CHAR_LOWERCASE_B || string_p[1] == LIT_CHAR_UPPERCASE_B)
{
radix = 2;
@@ -79,7 +84,7 @@ ecma_bigint_parse_string (const lit_utf8_byte_t *string_p, /**< string represena
}
else if (size == 0)
{
if (!throw_syntax_error)
if (options & ECMA_BIGINT_PARSE_DISALLOW_SYNTAX_ERROR)
{
return ECMA_VALUE_FALSE;
}
@@ -97,6 +102,7 @@ ecma_bigint_parse_string (const lit_utf8_byte_t *string_p, /**< string represena
if (string_p == string_end_p)
{
sign = 0;
result_p = ecma_bigint_create (0);
}
else
@@ -126,7 +132,7 @@ ecma_bigint_parse_string (const lit_utf8_byte_t *string_p, /**< string represena
ecma_deref_bigint (result_p);
}
if (!throw_syntax_error)
if (options & ECMA_BIGINT_PARSE_DISALLOW_SYNTAX_ERROR)
{
return ECMA_VALUE_FALSE;
}
@@ -145,6 +151,10 @@ ecma_bigint_parse_string (const lit_utf8_byte_t *string_p, /**< string represena
if (JERRY_UNLIKELY (result_p == NULL))
{
if (options & ECMA_BIGINT_PARSE_DISALLOW_MEMORY_ERROR)
{
return ECMA_VALUE_NULL;
}
return ecma_bigint_raise_memory_error ();
}
@@ -160,13 +170,12 @@ ecma_bigint_parse_string (const lit_utf8_byte_t *string_p, /**< string represena
*/
ecma_value_t
ecma_bigint_parse_string_value (ecma_value_t string, /**< ecma string */
bool throw_syntax_error) /**< true, if syntax errors should be thrown
* otherwise ECMA_VALUE_FALSE is returned on syntax error */
uint32_t options) /**< ecma_bigint_parse_string_options_t option bits */
{
JERRY_ASSERT (ecma_is_value_string (string));
ECMA_STRING_TO_UTF8_STRING (ecma_get_string_from_value (string), string_buffer_p, string_buffer_size);
ecma_value_t result = ecma_bigint_parse_string (string_buffer_p, string_buffer_size, throw_syntax_error);
ecma_value_t result = ecma_bigint_parse_string (string_buffer_p, string_buffer_size, options);
ECMA_FINALIZE_UTF8_STRING (string_buffer_p, string_buffer_size);
return result;
@@ -415,7 +424,7 @@ ecma_bigint_to_bigint (ecma_value_t value) /**< any value */
return ecma_raise_type_error (ECMA_ERR_MSG ("Value cannot be converted to BigInt"));
}
return ecma_bigint_parse_string_value (value, true);
return ecma_bigint_parse_string_value (value, ECMA_BIGINT_PARSE_NO_OPTIONS);
} /* ecma_bigint_to_bigint */
/**
+15 -2
View File
@@ -25,9 +25,22 @@
*/
#define ECMA_BIGINT_SIGN 0x1
/**
* Flags for ecma_bigint_parse_string.
*/
typedef enum
{
ECMA_BIGINT_PARSE_NO_OPTIONS = 0, /**< no options */
ECMA_BIGINT_PARSE_SET_NEGATIVE = (1 << 0), /**< return with a negative BigInt value */
ECMA_BIGINT_PARSE_DISALLOW_SYNTAX_ERROR = (1 << 1), /**< don't throw SyntaxError,
* return with ECMA_VALUE_FALSE */
ECMA_BIGINT_PARSE_DISALLOW_MEMORY_ERROR = (1 << 2), /**< don't throw out-of-memory error,
* return with ECMA_VALUE_NULL instead */
} ecma_bigint_parse_string_options_t;
ecma_value_t ecma_bigint_parse_string (const lit_utf8_byte_t *string_p, lit_utf8_size_t size,
bool throw_syntax_error);
ecma_value_t ecma_bigint_parse_string_value (ecma_value_t string, bool throw_syntax_error);
uint32_t options);
ecma_value_t ecma_bigint_parse_string_value (ecma_value_t string, uint32_t options);
ecma_string_t *ecma_bigint_to_string (ecma_value_t value, ecma_bigint_digit_t radix);
ecma_value_t ecma_bigint_number_to_bigint (ecma_number_t number);
ecma_value_t ecma_bigint_to_bigint (ecma_value_t value);
+2 -2
View File
@@ -171,7 +171,7 @@ ecma_op_abstract_equality_compare (ecma_value_t x, /**< first operand */
if (ecma_is_value_string (y))
{
ecma_value_t bigint = ecma_bigint_parse_string_value (y, false);
ecma_value_t bigint = ecma_bigint_parse_string_value (y, ECMA_BIGINT_PARSE_DISALLOW_SYNTAX_ERROR);
if (ECMA_IS_VALUE_ERROR (bigint)
|| bigint == ECMA_VALUE_FALSE)
@@ -483,7 +483,7 @@ ecma_op_abstract_relational_compare (ecma_value_t x, /**< first operand */
}
else if (ecma_is_value_string (py))
{
ret_value = ecma_bigint_parse_string_value (py, false);
ret_value = ecma_bigint_parse_string_value (py, ECMA_BIGINT_PARSE_DISALLOW_SYNTAX_ERROR);
if (!ECMA_IS_VALUE_ERROR (ret_value))
{