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;
|
return ret;
|
||||||
} /* lexer_parse_identifier_or_keyword */
|
} /* 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
|
static token
|
||||||
parse_number (void)
|
lexer_parse_number (void)
|
||||||
{
|
{
|
||||||
ecma_char_t c = LA (0);
|
ecma_char_t c = LA (0);
|
||||||
bool is_hex = false;
|
bool is_hex = false;
|
||||||
bool is_fp = false;
|
bool is_fp = false;
|
||||||
bool is_exp = false;
|
|
||||||
bool is_overflow = false;
|
|
||||||
ecma_number_t fp_res = .0;
|
ecma_number_t fp_res = .0;
|
||||||
size_t tok_length = 0, i;
|
size_t tok_length = 0, i;
|
||||||
uint32_t res = 0;
|
|
||||||
token known_token;
|
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;
|
is_hex = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (c == LIT_CHAR_DOT)
|
||||||
if (c == '.')
|
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (!isalpha (LA (1)));
|
JERRY_ASSERT (lit_char_is_decimal_digit (LA (1)));
|
||||||
is_fp = true;
|
is_fp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -834,189 +835,149 @@ parse_number (void)
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
c = LA (0);
|
c = LA (0);
|
||||||
if (!isxdigit (c))
|
if (!lit_char_is_hex_digit (c))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
consume_char ();
|
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));
|
lit_utf8_iterator_get_offset (&src_iter));
|
||||||
}
|
}
|
||||||
|
|
||||||
tok_length = (size_t) (lit_utf8_iterator_get_ptr (&src_iter) - token_start);
|
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++)
|
for (i = 0; i < tok_length; i++)
|
||||||
{
|
{
|
||||||
if (!is_overflow)
|
fp_res = fp_res * 16 + (ecma_number_t) lit_char_hex_to_int (token_start[i]);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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
|
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;
|
fp_res = fp_res * 10 + (ecma_number_t) lit_char_hex_to_int (token_start[i]);
|
||||||
is_overflow = true;
|
|
||||||
res = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
known_token = convert_seen_num_to_token (fp_res);
|
||||||
token_start = NULL;
|
token_start = NULL;
|
||||||
return known_token;
|
return known_token;
|
||||||
}
|
}
|
||||||
else
|
} /* lexer_parse_number */
|
||||||
{
|
|
||||||
known_token = create_token (TOK_SMALL_INT, (uint8_t) res);
|
|
||||||
token_start = NULL;
|
|
||||||
return known_token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse string literal (ECMA-262 v5, 7.8.4)
|
* Parse string literal (ECMA-262 v5, 7.8.4)
|
||||||
@@ -1243,9 +1204,12 @@ lexer_next_token_private (void)
|
|||||||
return lexer_parse_identifier_or_keyword ();
|
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')
|
if (c == '\n')
|
||||||
|
|||||||
Reference in New Issue
Block a user