Simplify lexer_parse_number (parse_number) and add unicode support to the function.
JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
This commit is contained in:
+127
-163
@@ -794,34 +794,35 @@ lexer_parse_identifier_or_keyword (void)
|
||||
return ret;
|
||||
} /* lexer_parse_identifier_or_keyword */
|
||||
|
||||
/* In this function we cannot use strtol function
|
||||
since there is no octal literals in ECMAscript. */
|
||||
/**
|
||||
* Parse numeric literal (ECMA-262, v5, 7.8.3)
|
||||
*
|
||||
* @return token of TOK_SMALL_INT or TOK_NUMBER types
|
||||
*/
|
||||
static token
|
||||
parse_number (void)
|
||||
lexer_parse_number (void)
|
||||
{
|
||||
ecma_char_t c = LA (0);
|
||||
bool is_hex = false;
|
||||
bool is_fp = false;
|
||||
bool is_exp = false;
|
||||
bool is_overflow = false;
|
||||
ecma_number_t fp_res = .0;
|
||||
size_t tok_length = 0, i;
|
||||
uint32_t res = 0;
|
||||
token known_token;
|
||||
|
||||
JERRY_ASSERT (isdigit (c) || c == '.');
|
||||
JERRY_ASSERT (lit_char_is_decimal_digit (c)
|
||||
|| c == LIT_CHAR_DOT);
|
||||
|
||||
if (c == '0')
|
||||
if (c == LIT_CHAR_0)
|
||||
{
|
||||
if (LA (1) == 'x' || LA (1) == 'X')
|
||||
if (LA (1) == LIT_CHAR_LOWERCASE_X
|
||||
|| LA (1) == LIT_CHAR_UPPERCASE_X)
|
||||
{
|
||||
is_hex = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '.')
|
||||
else if (c == LIT_CHAR_DOT)
|
||||
{
|
||||
JERRY_ASSERT (!isalpha (LA (1)));
|
||||
JERRY_ASSERT (lit_char_is_decimal_digit (LA (1)));
|
||||
is_fp = true;
|
||||
}
|
||||
|
||||
@@ -834,189 +835,149 @@ parse_number (void)
|
||||
while (true)
|
||||
{
|
||||
c = LA (0);
|
||||
if (!isxdigit (c))
|
||||
if (!lit_char_is_hex_digit (c))
|
||||
{
|
||||
break;
|
||||
}
|
||||
consume_char ();
|
||||
}
|
||||
|
||||
if (isalpha (c) || c == '_' || c == '$')
|
||||
if (lexer_is_char_can_be_identifier_start (c))
|
||||
{
|
||||
PARSE_ERROR ("Integer literal shall not contain non-digit characters",
|
||||
PARSE_ERROR ("Identifier just after integer literal",
|
||||
lit_utf8_iterator_get_offset (&src_iter));
|
||||
}
|
||||
|
||||
tok_length = (size_t) (lit_utf8_iterator_get_ptr (&src_iter) - token_start);
|
||||
|
||||
/* token is constructed at end of function */
|
||||
for (i = 0; i < tok_length; i++)
|
||||
{
|
||||
if (!is_overflow)
|
||||
{
|
||||
res = (res << 4) + lit_char_hex_to_int (token_start[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_res = fp_res * 16 + (ecma_number_t) lit_char_hex_to_int (token_start[i]);
|
||||
}
|
||||
|
||||
if (res > 255)
|
||||
{
|
||||
fp_res = (ecma_number_t) res;
|
||||
is_overflow = true;
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_overflow)
|
||||
{
|
||||
known_token = convert_seen_num_to_token (fp_res);
|
||||
token_start = NULL;
|
||||
return known_token;
|
||||
}
|
||||
else
|
||||
{
|
||||
known_token = create_token (TOK_SMALL_INT, (uint8_t) res);
|
||||
token_start = NULL;
|
||||
return known_token;
|
||||
}
|
||||
}
|
||||
|
||||
JERRY_ASSERT (!is_hex && !is_exp);
|
||||
|
||||
new_token ();
|
||||
|
||||
// Eat up '.'
|
||||
if (is_fp)
|
||||
{
|
||||
consume_char ();
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
c = LA (0);
|
||||
if (is_fp && c == '.')
|
||||
{
|
||||
FIXME (/* This is wrong: 1..toString (). */)
|
||||
PARSE_ERROR ("Integer literal shall not contain more than one dot character",
|
||||
lit_utf8_iterator_get_offset (&src_iter));
|
||||
}
|
||||
if (is_exp && (c == 'e' || c == 'E'))
|
||||
{
|
||||
PARSE_ERROR ("Integer literal shall not contain more than exponential marker ('e' or 'E')",
|
||||
lit_utf8_iterator_get_offset (&src_iter));
|
||||
}
|
||||
|
||||
if (c == '.')
|
||||
{
|
||||
if (isalpha (LA (1)) || LA (1) == '_' || LA (1) == '$')
|
||||
{
|
||||
PARSE_ERROR ("Integer literal shall not contain non-digit character after got character",
|
||||
lit_utf8_iterator_get_offset (&src_iter));
|
||||
}
|
||||
is_fp = true;
|
||||
consume_char ();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == 'e' || c == 'E')
|
||||
{
|
||||
if (LA (1) == '-' || LA (1) == '+')
|
||||
{
|
||||
consume_char ();
|
||||
}
|
||||
if (!isdigit (LA (1)))
|
||||
{
|
||||
PARSE_ERROR ("Integer literal shall not contain non-digit character after exponential marker ('e' or 'E')",
|
||||
lit_utf8_iterator_get_offset (&src_iter));
|
||||
}
|
||||
is_exp = true;
|
||||
consume_char ();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isalpha (c) || c == '_' || c == '$')
|
||||
{
|
||||
PARSE_ERROR ("Integer literal shall not contain non-digit characters",
|
||||
lit_utf8_iterator_get_offset (&src_iter));
|
||||
}
|
||||
|
||||
if (!isdigit (c))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
consume_char ();
|
||||
}
|
||||
|
||||
tok_length = (size_t) (lit_utf8_iterator_get_ptr (&src_iter) - token_start);
|
||||
if (is_fp || is_exp)
|
||||
{
|
||||
ecma_number_t res = ecma_utf8_string_to_number (token_start, (jerry_api_size_t) tok_length);
|
||||
JERRY_ASSERT (!ecma_number_is_nan (res));
|
||||
known_token = convert_seen_num_to_token (res);
|
||||
token_start = NULL;
|
||||
return known_token;
|
||||
}
|
||||
|
||||
if (*token_start == '0' && tok_length != 1)
|
||||
{
|
||||
if (strict_mode)
|
||||
{
|
||||
PARSE_ERROR ("Octal tnteger literals are not allowed in strict mode", token_start - buffer_start);
|
||||
}
|
||||
for (i = 0; i < tok_length; i++)
|
||||
{
|
||||
if (!is_overflow)
|
||||
{
|
||||
res = res * 8 + lit_char_hex_to_int (token_start[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_res = fp_res * 8 + (ecma_number_t) lit_char_hex_to_int (token_start[i]);
|
||||
}
|
||||
if (res > 255)
|
||||
{
|
||||
fp_res = (ecma_number_t) res;
|
||||
is_overflow = true;
|
||||
res = 0;
|
||||
}
|
||||
fp_res = fp_res * 16 + (ecma_number_t) lit_char_hex_to_int (token_start[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < tok_length; i++)
|
||||
bool is_exp = false;
|
||||
|
||||
new_token ();
|
||||
|
||||
// Eat up '.'
|
||||
if (is_fp)
|
||||
{
|
||||
if (!is_overflow)
|
||||
consume_char ();
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
c = LA (0);
|
||||
|
||||
if (c == LIT_CHAR_DOT)
|
||||
{
|
||||
res = res * 10 + lit_char_hex_to_int (token_start[i]);
|
||||
if (is_fp)
|
||||
{
|
||||
/* token is constructed at end of function */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_fp = true;
|
||||
consume_char ();
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (c == LIT_CHAR_LOWERCASE_E
|
||||
|| c == LIT_CHAR_UPPERCASE_E)
|
||||
{
|
||||
if (is_exp)
|
||||
{
|
||||
PARSE_ERROR ("Numeric literal shall not contain more than exponential marker ('e' or 'E')",
|
||||
lit_utf8_iterator_get_offset (&src_iter));
|
||||
}
|
||||
else
|
||||
{
|
||||
is_exp = true;
|
||||
consume_char ();
|
||||
|
||||
if (LA (0) == LIT_CHAR_MINUS
|
||||
|| LA (0) == LIT_CHAR_PLUS)
|
||||
{
|
||||
consume_char ();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (!lit_char_is_decimal_digit (c))
|
||||
{
|
||||
if (lexer_is_char_can_be_identifier_start (c))
|
||||
{
|
||||
PARSE_ERROR ("Numeric literal shall not contain non-numeric characters",
|
||||
lit_utf8_iterator_get_offset (&src_iter));
|
||||
}
|
||||
|
||||
/* token is constructed at end of function */
|
||||
break;
|
||||
}
|
||||
|
||||
consume_char ();
|
||||
}
|
||||
|
||||
tok_length = (size_t) (lit_utf8_iterator_get_ptr (&src_iter) - token_start);
|
||||
|
||||
if (is_fp || is_exp)
|
||||
{
|
||||
ecma_number_t res = ecma_utf8_string_to_number (token_start, (jerry_api_size_t) tok_length);
|
||||
JERRY_ASSERT (!ecma_number_is_nan (res));
|
||||
|
||||
known_token = convert_seen_num_to_token (res);
|
||||
token_start = NULL;
|
||||
|
||||
return known_token;
|
||||
}
|
||||
else if (*token_start == LIT_CHAR_0
|
||||
&& tok_length != 1)
|
||||
{
|
||||
/* Octal integer literals */
|
||||
if (strict_mode)
|
||||
{
|
||||
PARSE_ERROR ("Octal integer literals are not allowed in strict mode", token_start - buffer_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
fp_res = fp_res * 10 + (ecma_number_t) lit_char_hex_to_int (token_start[i]);
|
||||
/* token is constructed at end of function */
|
||||
|
||||
for (i = 0; i < tok_length; i++)
|
||||
{
|
||||
fp_res = fp_res * 8 + (ecma_number_t) lit_char_hex_to_int (token_start[i]);
|
||||
}
|
||||
}
|
||||
if (res > 255)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* token is constructed at end of function */
|
||||
|
||||
for (i = 0; i < tok_length; i++)
|
||||
{
|
||||
fp_res = (ecma_number_t) res;
|
||||
is_overflow = true;
|
||||
res = 0;
|
||||
fp_res = fp_res * 10 + (ecma_number_t) lit_char_hex_to_int (token_start[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_overflow)
|
||||
if (fp_res >= 0 && fp_res <= 255 && (uint8_t) fp_res == fp_res)
|
||||
{
|
||||
known_token = create_token (TOK_SMALL_INT, (uint8_t) fp_res);
|
||||
token_start = NULL;
|
||||
return known_token;
|
||||
}
|
||||
else
|
||||
{
|
||||
known_token = convert_seen_num_to_token (fp_res);
|
||||
token_start = NULL;
|
||||
return known_token;
|
||||
}
|
||||
else
|
||||
{
|
||||
known_token = create_token (TOK_SMALL_INT, (uint8_t) res);
|
||||
token_start = NULL;
|
||||
return known_token;
|
||||
}
|
||||
}
|
||||
} /* lexer_parse_number */
|
||||
|
||||
/**
|
||||
* Parse string literal (ECMA-262 v5, 7.8.4)
|
||||
@@ -1243,9 +1204,12 @@ lexer_next_token_private (void)
|
||||
return lexer_parse_identifier_or_keyword ();
|
||||
}
|
||||
|
||||
if (isdigit (c) || (c == '.' && isdigit (LA (1))))
|
||||
/* ECMA-262 v5, 7.8.3, Numeric literal */
|
||||
if (lit_char_is_decimal_digit (c)
|
||||
|| (c == LIT_CHAR_DOT
|
||||
&& lit_char_is_decimal_digit (LA (1))))
|
||||
{
|
||||
return parse_number ();
|
||||
return lexer_parse_number ();
|
||||
}
|
||||
|
||||
if (c == '\n')
|
||||
|
||||
Reference in New Issue
Block a user