1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include "ecma-alloc.h" 17425bb815Sopenharmony_ci#include "ecma-helpers.h" 18425bb815Sopenharmony_ci#include "ecma-function-object.h" 19425bb815Sopenharmony_ci#include "ecma-literal-storage.h" 20425bb815Sopenharmony_ci#include "js-parser-internal.h" 21425bb815Sopenharmony_ci#include "lit-char-helpers.h" 22425bb815Sopenharmony_ci#include "jcontext.h" 23425bb815Sopenharmony_ci 24425bb815Sopenharmony_ci#if ENABLED (JERRY_PARSER) 25425bb815Sopenharmony_ci 26425bb815Sopenharmony_ci/** \addtogroup parser Parser 27425bb815Sopenharmony_ci * @{ 28425bb815Sopenharmony_ci * 29425bb815Sopenharmony_ci * \addtogroup jsparser JavaScript 30425bb815Sopenharmony_ci * @{ 31425bb815Sopenharmony_ci * 32425bb815Sopenharmony_ci * \addtogroup jsparser_lexer Lexer 33425bb815Sopenharmony_ci * @{ 34425bb815Sopenharmony_ci */ 35425bb815Sopenharmony_ci 36425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (LEXER_NUMBER_BINARY > LEXER_NUMBER_OCTAL, 37425bb815Sopenharmony_ci lexer_number_binary_must_be_greater_than_lexer_number_octal); 38425bb815Sopenharmony_ci 39425bb815Sopenharmony_ci/** 40425bb815Sopenharmony_ci * Check whether the UTF-8 intermediate is an octet or not 41425bb815Sopenharmony_ci */ 42425bb815Sopenharmony_ci#define IS_UTF8_INTERMEDIATE_OCTET(byte) (((byte) & LIT_UTF8_EXTRA_BYTE_MASK) == LIT_UTF8_2_BYTE_CODE_POINT_MIN) 43425bb815Sopenharmony_ci 44425bb815Sopenharmony_ci/** 45425bb815Sopenharmony_ci * Align column to the next tab position. 46425bb815Sopenharmony_ci * 47425bb815Sopenharmony_ci * @return aligned position 48425bb815Sopenharmony_ci */ 49425bb815Sopenharmony_cistatic parser_line_counter_t 50425bb815Sopenharmony_cialign_column_to_tab (parser_line_counter_t column) /**< current column */ 51425bb815Sopenharmony_ci{ 52425bb815Sopenharmony_ci /* Tab aligns to zero column start position. */ 53425bb815Sopenharmony_ci return (parser_line_counter_t) (((column + (8u - 1u)) & ~ECMA_STRING_CONTAINER_MASK) + 1u); 54425bb815Sopenharmony_ci} /* align_column_to_tab */ 55425bb815Sopenharmony_ci 56425bb815Sopenharmony_ci/** 57425bb815Sopenharmony_ci * Parse hexadecimal character sequence 58425bb815Sopenharmony_ci * 59425bb815Sopenharmony_ci * @return character value or UINT32_MAX on error 60425bb815Sopenharmony_ci */ 61425bb815Sopenharmony_cistatic lit_code_point_t 62425bb815Sopenharmony_cilexer_hex_to_code_point (const uint8_t *source_p, /**< current source position */ 63425bb815Sopenharmony_ci parser_line_counter_t length) /**< source length */ 64425bb815Sopenharmony_ci{ 65425bb815Sopenharmony_ci lit_code_point_t result = 0; 66425bb815Sopenharmony_ci 67425bb815Sopenharmony_ci do 68425bb815Sopenharmony_ci { 69425bb815Sopenharmony_ci uint32_t byte = *source_p++; 70425bb815Sopenharmony_ci 71425bb815Sopenharmony_ci result <<= 4; 72425bb815Sopenharmony_ci 73425bb815Sopenharmony_ci if (byte >= LIT_CHAR_0 && byte <= LIT_CHAR_9) 74425bb815Sopenharmony_ci { 75425bb815Sopenharmony_ci result += byte - LIT_CHAR_0; 76425bb815Sopenharmony_ci } 77425bb815Sopenharmony_ci else 78425bb815Sopenharmony_ci { 79425bb815Sopenharmony_ci byte = LEXER_TO_ASCII_LOWERCASE (byte); 80425bb815Sopenharmony_ci if (byte >= LIT_CHAR_LOWERCASE_A && byte <= LIT_CHAR_LOWERCASE_F) 81425bb815Sopenharmony_ci { 82425bb815Sopenharmony_ci result += byte - (LIT_CHAR_LOWERCASE_A - 10); 83425bb815Sopenharmony_ci } 84425bb815Sopenharmony_ci else 85425bb815Sopenharmony_ci { 86425bb815Sopenharmony_ci return UINT32_MAX; 87425bb815Sopenharmony_ci } 88425bb815Sopenharmony_ci } 89425bb815Sopenharmony_ci } 90425bb815Sopenharmony_ci while (--length > 0); 91425bb815Sopenharmony_ci 92425bb815Sopenharmony_ci return result; 93425bb815Sopenharmony_ci} /* lexer_hex_to_code_point */ 94425bb815Sopenharmony_ci 95425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 96425bb815Sopenharmony_ci 97425bb815Sopenharmony_ci/** 98425bb815Sopenharmony_ci * Parse hexadecimal character sequence enclosed in braces 99425bb815Sopenharmony_ci * 100425bb815Sopenharmony_ci * @return character value or UINT32_MAX on error 101425bb815Sopenharmony_ci */ 102425bb815Sopenharmony_cistatic lit_code_point_t 103425bb815Sopenharmony_cilexer_hex_in_braces_to_code_point (const uint8_t *source_p, /**< current source position */ 104425bb815Sopenharmony_ci const uint8_t *source_end_p, /**< source end */ 105425bb815Sopenharmony_ci uint32_t *length_p) /**< [out] length of the sequence */ 106425bb815Sopenharmony_ci{ 107425bb815Sopenharmony_ci lit_code_point_t result = 0; 108425bb815Sopenharmony_ci /* Four is the size of \u{} sequence. */ 109425bb815Sopenharmony_ci uint32_t length = 4; 110425bb815Sopenharmony_ci 111425bb815Sopenharmony_ci JERRY_ASSERT (source_p[-1] == LIT_CHAR_LEFT_BRACE); 112425bb815Sopenharmony_ci JERRY_ASSERT (source_p < source_end_p); 113425bb815Sopenharmony_ci 114425bb815Sopenharmony_ci do 115425bb815Sopenharmony_ci { 116425bb815Sopenharmony_ci uint32_t byte = *source_p++; 117425bb815Sopenharmony_ci 118425bb815Sopenharmony_ci result <<= 4; 119425bb815Sopenharmony_ci 120425bb815Sopenharmony_ci if (byte >= LIT_CHAR_0 && byte <= LIT_CHAR_9) 121425bb815Sopenharmony_ci { 122425bb815Sopenharmony_ci result += byte - LIT_CHAR_0; 123425bb815Sopenharmony_ci } 124425bb815Sopenharmony_ci else 125425bb815Sopenharmony_ci { 126425bb815Sopenharmony_ci byte = LEXER_TO_ASCII_LOWERCASE (byte); 127425bb815Sopenharmony_ci if (byte >= LIT_CHAR_LOWERCASE_A && byte <= LIT_CHAR_LOWERCASE_F) 128425bb815Sopenharmony_ci { 129425bb815Sopenharmony_ci result += byte - (LIT_CHAR_LOWERCASE_A - 10); 130425bb815Sopenharmony_ci } 131425bb815Sopenharmony_ci else 132425bb815Sopenharmony_ci { 133425bb815Sopenharmony_ci return UINT32_MAX; 134425bb815Sopenharmony_ci } 135425bb815Sopenharmony_ci } 136425bb815Sopenharmony_ci 137425bb815Sopenharmony_ci if (result >= (LIT_UNICODE_CODE_POINT_MAX + 1) || source_p >= source_end_p) 138425bb815Sopenharmony_ci { 139425bb815Sopenharmony_ci return UINT32_MAX; 140425bb815Sopenharmony_ci } 141425bb815Sopenharmony_ci length++; 142425bb815Sopenharmony_ci } 143425bb815Sopenharmony_ci while (*source_p != LIT_CHAR_RIGHT_BRACE); 144425bb815Sopenharmony_ci 145425bb815Sopenharmony_ci *length_p = length; 146425bb815Sopenharmony_ci return result; 147425bb815Sopenharmony_ci} /* lexer_hex_in_braces_to_code_point */ 148425bb815Sopenharmony_ci 149425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 150425bb815Sopenharmony_ci 151425bb815Sopenharmony_ci/** 152425bb815Sopenharmony_ci * Parse hexadecimal character sequence 153425bb815Sopenharmony_ci * 154425bb815Sopenharmony_ci * @return character value 155425bb815Sopenharmony_ci */ 156425bb815Sopenharmony_cistatic lit_code_point_t 157425bb815Sopenharmony_cilexer_unchecked_hex_to_character (const uint8_t **source_p) /**< [in, out] current source position */ 158425bb815Sopenharmony_ci{ 159425bb815Sopenharmony_ci lit_code_point_t result = 0; 160425bb815Sopenharmony_ci const uint8_t *char_p = *source_p; 161425bb815Sopenharmony_ci uint32_t length = (char_p[-1] == LIT_CHAR_LOWERCASE_U) ? 4 : 2; 162425bb815Sopenharmony_ci 163425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 164425bb815Sopenharmony_ci if (char_p[0] == LIT_CHAR_LEFT_BRACE) 165425bb815Sopenharmony_ci { 166425bb815Sopenharmony_ci length = 0; 167425bb815Sopenharmony_ci char_p++; 168425bb815Sopenharmony_ci } 169425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 170425bb815Sopenharmony_ci 171425bb815Sopenharmony_ci while (true) 172425bb815Sopenharmony_ci { 173425bb815Sopenharmony_ci uint32_t byte = *char_p++; 174425bb815Sopenharmony_ci 175425bb815Sopenharmony_ci result <<= 4; 176425bb815Sopenharmony_ci 177425bb815Sopenharmony_ci if (byte >= LIT_CHAR_0 && byte <= LIT_CHAR_9) 178425bb815Sopenharmony_ci { 179425bb815Sopenharmony_ci result += byte - LIT_CHAR_0; 180425bb815Sopenharmony_ci } 181425bb815Sopenharmony_ci else 182425bb815Sopenharmony_ci { 183425bb815Sopenharmony_ci JERRY_ASSERT ((byte >= LIT_CHAR_LOWERCASE_A && byte <= LIT_CHAR_LOWERCASE_F) 184425bb815Sopenharmony_ci || (byte >= LIT_CHAR_UPPERCASE_A && byte <= LIT_CHAR_UPPERCASE_F)); 185425bb815Sopenharmony_ci 186425bb815Sopenharmony_ci result += LEXER_TO_ASCII_LOWERCASE (byte) - (LIT_CHAR_LOWERCASE_A - 10); 187425bb815Sopenharmony_ci } 188425bb815Sopenharmony_ci 189425bb815Sopenharmony_ci JERRY_ASSERT (result <= LIT_UNICODE_CODE_POINT_MAX); 190425bb815Sopenharmony_ci 191425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 192425bb815Sopenharmony_ci if (length == 0) 193425bb815Sopenharmony_ci { 194425bb815Sopenharmony_ci if (*char_p != LIT_CHAR_RIGHT_BRACE) 195425bb815Sopenharmony_ci { 196425bb815Sopenharmony_ci continue; 197425bb815Sopenharmony_ci } 198425bb815Sopenharmony_ci *source_p = char_p + 1; 199425bb815Sopenharmony_ci return result; 200425bb815Sopenharmony_ci } 201425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 202425bb815Sopenharmony_ci 203425bb815Sopenharmony_ci if (--length == 0) 204425bb815Sopenharmony_ci { 205425bb815Sopenharmony_ci *source_p = char_p; 206425bb815Sopenharmony_ci return result; 207425bb815Sopenharmony_ci } 208425bb815Sopenharmony_ci } 209425bb815Sopenharmony_ci} /* lexer_unchecked_hex_to_character */ 210425bb815Sopenharmony_ci 211425bb815Sopenharmony_ci/** 212425bb815Sopenharmony_ci * Skip space mode 213425bb815Sopenharmony_ci */ 214425bb815Sopenharmony_citypedef enum 215425bb815Sopenharmony_ci{ 216425bb815Sopenharmony_ci LEXER_SKIP_SPACES, /**< skip spaces mode */ 217425bb815Sopenharmony_ci LEXER_SKIP_SINGLE_LINE_COMMENT, /**< parse single line comment */ 218425bb815Sopenharmony_ci LEXER_SKIP_MULTI_LINE_COMMENT, /**< parse multi line comment */ 219425bb815Sopenharmony_ci} skip_mode_t; 220425bb815Sopenharmony_ci 221425bb815Sopenharmony_ci/** 222425bb815Sopenharmony_ci * Skip spaces. 223425bb815Sopenharmony_ci */ 224425bb815Sopenharmony_cistatic void 225425bb815Sopenharmony_cilexer_skip_spaces (parser_context_t *context_p) /**< context */ 226425bb815Sopenharmony_ci{ 227425bb815Sopenharmony_ci skip_mode_t mode = LEXER_SKIP_SPACES; 228425bb815Sopenharmony_ci const uint8_t *source_end_p = context_p->source_end_p; 229425bb815Sopenharmony_ci 230425bb815Sopenharmony_ci if (context_p->token.flags & LEXER_NO_SKIP_SPACES) 231425bb815Sopenharmony_ci { 232425bb815Sopenharmony_ci context_p->token.flags &= (uint8_t) ~LEXER_NO_SKIP_SPACES; 233425bb815Sopenharmony_ci return; 234425bb815Sopenharmony_ci } 235425bb815Sopenharmony_ci 236425bb815Sopenharmony_ci context_p->token.flags = 0; 237425bb815Sopenharmony_ci 238425bb815Sopenharmony_ci while (true) 239425bb815Sopenharmony_ci { 240425bb815Sopenharmony_ci if (context_p->source_p >= source_end_p) 241425bb815Sopenharmony_ci { 242425bb815Sopenharmony_ci if (mode == LEXER_SKIP_MULTI_LINE_COMMENT) 243425bb815Sopenharmony_ci { 244425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_UNTERMINATED_MULTILINE_COMMENT); 245425bb815Sopenharmony_ci } 246425bb815Sopenharmony_ci return; 247425bb815Sopenharmony_ci } 248425bb815Sopenharmony_ci 249425bb815Sopenharmony_ci switch (context_p->source_p[0]) 250425bb815Sopenharmony_ci { 251425bb815Sopenharmony_ci case LIT_CHAR_CR: 252425bb815Sopenharmony_ci { 253425bb815Sopenharmony_ci if (context_p->source_p + 1 < source_end_p 254425bb815Sopenharmony_ci && context_p->source_p[1] == LIT_CHAR_LF) 255425bb815Sopenharmony_ci { 256425bb815Sopenharmony_ci context_p->source_p++; 257425bb815Sopenharmony_ci } 258425bb815Sopenharmony_ci /* FALLTHRU */ 259425bb815Sopenharmony_ci } 260425bb815Sopenharmony_ci 261425bb815Sopenharmony_ci case LIT_CHAR_LF: 262425bb815Sopenharmony_ci { 263425bb815Sopenharmony_ci context_p->line++; 264425bb815Sopenharmony_ci context_p->column = 0; 265425bb815Sopenharmony_ci context_p->token.flags = LEXER_WAS_NEWLINE; 266425bb815Sopenharmony_ci 267425bb815Sopenharmony_ci if (mode == LEXER_SKIP_SINGLE_LINE_COMMENT) 268425bb815Sopenharmony_ci { 269425bb815Sopenharmony_ci mode = LEXER_SKIP_SPACES; 270425bb815Sopenharmony_ci } 271425bb815Sopenharmony_ci /* FALLTHRU */ 272425bb815Sopenharmony_ci } 273425bb815Sopenharmony_ci 274425bb815Sopenharmony_ci case LIT_CHAR_VTAB: 275425bb815Sopenharmony_ci case LIT_CHAR_FF: 276425bb815Sopenharmony_ci case LIT_CHAR_SP: 277425bb815Sopenharmony_ci { 278425bb815Sopenharmony_ci context_p->source_p++; 279425bb815Sopenharmony_ci context_p->column++; 280425bb815Sopenharmony_ci continue; 281425bb815Sopenharmony_ci } 282425bb815Sopenharmony_ci 283425bb815Sopenharmony_ci case LIT_CHAR_TAB: 284425bb815Sopenharmony_ci { 285425bb815Sopenharmony_ci context_p->column = align_column_to_tab (context_p->column); 286425bb815Sopenharmony_ci context_p->source_p++; 287425bb815Sopenharmony_ci continue; 288425bb815Sopenharmony_ci } 289425bb815Sopenharmony_ci 290425bb815Sopenharmony_ci case LIT_CHAR_SLASH: 291425bb815Sopenharmony_ci { 292425bb815Sopenharmony_ci if (mode == LEXER_SKIP_SPACES 293425bb815Sopenharmony_ci && context_p->source_p + 1 < source_end_p) 294425bb815Sopenharmony_ci { 295425bb815Sopenharmony_ci if (context_p->source_p[1] == LIT_CHAR_SLASH) 296425bb815Sopenharmony_ci { 297425bb815Sopenharmony_ci mode = LEXER_SKIP_SINGLE_LINE_COMMENT; 298425bb815Sopenharmony_ci } 299425bb815Sopenharmony_ci else if (context_p->source_p[1] == LIT_CHAR_ASTERISK) 300425bb815Sopenharmony_ci { 301425bb815Sopenharmony_ci mode = LEXER_SKIP_MULTI_LINE_COMMENT; 302425bb815Sopenharmony_ci context_p->token.line = context_p->line; 303425bb815Sopenharmony_ci context_p->token.column = context_p->column; 304425bb815Sopenharmony_ci } 305425bb815Sopenharmony_ci 306425bb815Sopenharmony_ci if (mode != LEXER_SKIP_SPACES) 307425bb815Sopenharmony_ci { 308425bb815Sopenharmony_ci context_p->source_p += 2; 309425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_LC (context_p->column, 2); 310425bb815Sopenharmony_ci continue; 311425bb815Sopenharmony_ci } 312425bb815Sopenharmony_ci } 313425bb815Sopenharmony_ci break; 314425bb815Sopenharmony_ci } 315425bb815Sopenharmony_ci 316425bb815Sopenharmony_ci case LIT_CHAR_ASTERISK: 317425bb815Sopenharmony_ci { 318425bb815Sopenharmony_ci if (mode == LEXER_SKIP_MULTI_LINE_COMMENT 319425bb815Sopenharmony_ci && context_p->source_p + 1 < source_end_p 320425bb815Sopenharmony_ci && context_p->source_p[1] == LIT_CHAR_SLASH) 321425bb815Sopenharmony_ci { 322425bb815Sopenharmony_ci mode = LEXER_SKIP_SPACES; 323425bb815Sopenharmony_ci context_p->source_p += 2; 324425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_LC (context_p->column, 2); 325425bb815Sopenharmony_ci continue; 326425bb815Sopenharmony_ci } 327425bb815Sopenharmony_ci break; 328425bb815Sopenharmony_ci } 329425bb815Sopenharmony_ci 330425bb815Sopenharmony_ci case 0xc2: 331425bb815Sopenharmony_ci { 332425bb815Sopenharmony_ci if (context_p->source_p + 1 < source_end_p 333425bb815Sopenharmony_ci && context_p->source_p[1] == 0xa0) 334425bb815Sopenharmony_ci { 335425bb815Sopenharmony_ci /* Codepoint \u00A0 */ 336425bb815Sopenharmony_ci context_p->source_p += 2; 337425bb815Sopenharmony_ci context_p->column++; 338425bb815Sopenharmony_ci continue; 339425bb815Sopenharmony_ci } 340425bb815Sopenharmony_ci break; 341425bb815Sopenharmony_ci } 342425bb815Sopenharmony_ci 343425bb815Sopenharmony_ci case LEXER_NEWLINE_LS_PS_BYTE_1: 344425bb815Sopenharmony_ci { 345425bb815Sopenharmony_ci JERRY_ASSERT (context_p->source_p + 2 < source_end_p); 346425bb815Sopenharmony_ci if (LEXER_NEWLINE_LS_PS_BYTE_23 (context_p->source_p)) 347425bb815Sopenharmony_ci { 348425bb815Sopenharmony_ci /* Codepoint \u2028 and \u2029 */ 349425bb815Sopenharmony_ci context_p->source_p += 3; 350425bb815Sopenharmony_ci context_p->line++; 351425bb815Sopenharmony_ci context_p->column = 1; 352425bb815Sopenharmony_ci context_p->token.flags = LEXER_WAS_NEWLINE; 353425bb815Sopenharmony_ci 354425bb815Sopenharmony_ci if (mode == LEXER_SKIP_SINGLE_LINE_COMMENT) 355425bb815Sopenharmony_ci { 356425bb815Sopenharmony_ci mode = LEXER_SKIP_SPACES; 357425bb815Sopenharmony_ci } 358425bb815Sopenharmony_ci continue; 359425bb815Sopenharmony_ci } 360425bb815Sopenharmony_ci break; 361425bb815Sopenharmony_ci } 362425bb815Sopenharmony_ci 363425bb815Sopenharmony_ci case 0xef: 364425bb815Sopenharmony_ci { 365425bb815Sopenharmony_ci if (context_p->source_p + 2 < source_end_p 366425bb815Sopenharmony_ci && context_p->source_p[1] == 0xbb 367425bb815Sopenharmony_ci && context_p->source_p[2] == 0xbf) 368425bb815Sopenharmony_ci { 369425bb815Sopenharmony_ci /* Codepoint \uFEFF */ 370425bb815Sopenharmony_ci context_p->source_p += 3; 371425bb815Sopenharmony_ci context_p->column++; 372425bb815Sopenharmony_ci continue; 373425bb815Sopenharmony_ci } 374425bb815Sopenharmony_ci break; 375425bb815Sopenharmony_ci } 376425bb815Sopenharmony_ci 377425bb815Sopenharmony_ci default: 378425bb815Sopenharmony_ci { 379425bb815Sopenharmony_ci break; 380425bb815Sopenharmony_ci } 381425bb815Sopenharmony_ci } 382425bb815Sopenharmony_ci 383425bb815Sopenharmony_ci if (mode == LEXER_SKIP_SPACES) 384425bb815Sopenharmony_ci { 385425bb815Sopenharmony_ci return; 386425bb815Sopenharmony_ci } 387425bb815Sopenharmony_ci 388425bb815Sopenharmony_ci context_p->source_p++; 389425bb815Sopenharmony_ci 390425bb815Sopenharmony_ci if (context_p->source_p < source_end_p 391425bb815Sopenharmony_ci && !IS_UTF8_INTERMEDIATE_OCTET (context_p->source_p[0])) 392425bb815Sopenharmony_ci { 393425bb815Sopenharmony_ci context_p->column++; 394425bb815Sopenharmony_ci } 395425bb815Sopenharmony_ci } 396425bb815Sopenharmony_ci} /* lexer_skip_spaces */ 397425bb815Sopenharmony_ci 398425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 399425bb815Sopenharmony_ci/** 400425bb815Sopenharmony_ci * Skip all the continuous empty statements. 401425bb815Sopenharmony_ci */ 402425bb815Sopenharmony_civoid 403425bb815Sopenharmony_cilexer_skip_empty_statements (parser_context_t *context_p) /**< context */ 404425bb815Sopenharmony_ci{ 405425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 406425bb815Sopenharmony_ci 407425bb815Sopenharmony_ci while (context_p->source_p < context_p->source_end_p 408425bb815Sopenharmony_ci && *context_p->source_p == LIT_CHAR_SEMICOLON) 409425bb815Sopenharmony_ci { 410425bb815Sopenharmony_ci lexer_consume_next_character (context_p); 411425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 412425bb815Sopenharmony_ci } 413425bb815Sopenharmony_ci 414425bb815Sopenharmony_ci context_p->token.flags = (uint8_t) (context_p->token.flags | LEXER_NO_SKIP_SPACES); 415425bb815Sopenharmony_ci} /* lexer_skip_empty_statements */ 416425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 417425bb815Sopenharmony_ci 418425bb815Sopenharmony_ci/** 419425bb815Sopenharmony_ci * Keyword data. 420425bb815Sopenharmony_ci */ 421425bb815Sopenharmony_citypedef struct 422425bb815Sopenharmony_ci{ 423425bb815Sopenharmony_ci const uint8_t *keyword_p; /**< keyword string */ 424425bb815Sopenharmony_ci lexer_token_type_t type; /**< keyword token type */ 425425bb815Sopenharmony_ci} keyword_string_t; 426425bb815Sopenharmony_ci 427425bb815Sopenharmony_ci/** 428425bb815Sopenharmony_ci * @{ 429425bb815Sopenharmony_ci * Keyword defines 430425bb815Sopenharmony_ci */ 431425bb815Sopenharmony_ci#define LEXER_KEYWORD(name, type) { (const uint8_t *) (name), (type) } 432425bb815Sopenharmony_ci#define LEXER_KEYWORD_LIST_LENGTH(name) (const uint8_t) (sizeof ((name)) / sizeof ((name)[0])) 433425bb815Sopenharmony_ci/** @} */ 434425bb815Sopenharmony_ci 435425bb815Sopenharmony_ci/** 436425bb815Sopenharmony_ci * Length of the shortest keyword. 437425bb815Sopenharmony_ci */ 438425bb815Sopenharmony_ci#define LEXER_KEYWORD_MIN_LENGTH 2 439425bb815Sopenharmony_ci 440425bb815Sopenharmony_ci/** 441425bb815Sopenharmony_ci * Length of the longest keyword. 442425bb815Sopenharmony_ci */ 443425bb815Sopenharmony_ci#define LEXER_KEYWORD_MAX_LENGTH 10 444425bb815Sopenharmony_ci 445425bb815Sopenharmony_ci/** 446425bb815Sopenharmony_ci * Keywords with 2 characters. 447425bb815Sopenharmony_ci */ 448425bb815Sopenharmony_cistatic const keyword_string_t keywords_with_length_2[] = 449425bb815Sopenharmony_ci{ 450425bb815Sopenharmony_ci LEXER_KEYWORD ("do", LEXER_KEYW_DO), 451425bb815Sopenharmony_ci LEXER_KEYWORD ("if", LEXER_KEYW_IF), 452425bb815Sopenharmony_ci LEXER_KEYWORD ("in", LEXER_KEYW_IN), 453425bb815Sopenharmony_ci}; 454425bb815Sopenharmony_ci 455425bb815Sopenharmony_ci/** 456425bb815Sopenharmony_ci * Keywords with 3 characters. 457425bb815Sopenharmony_ci */ 458425bb815Sopenharmony_cistatic const keyword_string_t keywords_with_length_3[] = 459425bb815Sopenharmony_ci{ 460425bb815Sopenharmony_ci LEXER_KEYWORD ("for", LEXER_KEYW_FOR), 461425bb815Sopenharmony_ci LEXER_KEYWORD ("let", LEXER_KEYW_LET), 462425bb815Sopenharmony_ci LEXER_KEYWORD ("new", LEXER_KEYW_NEW), 463425bb815Sopenharmony_ci LEXER_KEYWORD ("try", LEXER_KEYW_TRY), 464425bb815Sopenharmony_ci LEXER_KEYWORD ("var", LEXER_KEYW_VAR), 465425bb815Sopenharmony_ci}; 466425bb815Sopenharmony_ci 467425bb815Sopenharmony_ci/** 468425bb815Sopenharmony_ci * Keywords with 4 characters. 469425bb815Sopenharmony_ci */ 470425bb815Sopenharmony_cistatic const keyword_string_t keywords_with_length_4[] = 471425bb815Sopenharmony_ci{ 472425bb815Sopenharmony_ci LEXER_KEYWORD ("case", LEXER_KEYW_CASE), 473425bb815Sopenharmony_ci LEXER_KEYWORD ("else", LEXER_KEYW_ELSE), 474425bb815Sopenharmony_ci LEXER_KEYWORD ("enum", LEXER_KEYW_ENUM), 475425bb815Sopenharmony_ci LEXER_KEYWORD ("eval", LEXER_KEYW_EVAL), 476425bb815Sopenharmony_ci LEXER_KEYWORD ("null", LEXER_LIT_NULL), 477425bb815Sopenharmony_ci LEXER_KEYWORD ("this", LEXER_KEYW_THIS), 478425bb815Sopenharmony_ci LEXER_KEYWORD ("true", LEXER_LIT_TRUE), 479425bb815Sopenharmony_ci LEXER_KEYWORD ("void", LEXER_KEYW_VOID), 480425bb815Sopenharmony_ci LEXER_KEYWORD ("with", LEXER_KEYW_WITH), 481425bb815Sopenharmony_ci}; 482425bb815Sopenharmony_ci 483425bb815Sopenharmony_ci/** 484425bb815Sopenharmony_ci * Keywords with 5 characters. 485425bb815Sopenharmony_ci */ 486425bb815Sopenharmony_cistatic const keyword_string_t keywords_with_length_5[] = 487425bb815Sopenharmony_ci{ 488425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 489425bb815Sopenharmony_ci LEXER_KEYWORD ("async", LEXER_KEYW_ASYNC), 490425bb815Sopenharmony_ci LEXER_KEYWORD ("await", LEXER_KEYW_AWAIT), 491425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 492425bb815Sopenharmony_ci LEXER_KEYWORD ("break", LEXER_KEYW_BREAK), 493425bb815Sopenharmony_ci LEXER_KEYWORD ("catch", LEXER_KEYW_CATCH), 494425bb815Sopenharmony_ci LEXER_KEYWORD ("class", LEXER_KEYW_CLASS), 495425bb815Sopenharmony_ci LEXER_KEYWORD ("const", LEXER_KEYW_CONST), 496425bb815Sopenharmony_ci LEXER_KEYWORD ("false", LEXER_LIT_FALSE), 497425bb815Sopenharmony_ci LEXER_KEYWORD ("super", LEXER_KEYW_SUPER), 498425bb815Sopenharmony_ci LEXER_KEYWORD ("throw", LEXER_KEYW_THROW), 499425bb815Sopenharmony_ci LEXER_KEYWORD ("while", LEXER_KEYW_WHILE), 500425bb815Sopenharmony_ci LEXER_KEYWORD ("yield", LEXER_KEYW_YIELD), 501425bb815Sopenharmony_ci}; 502425bb815Sopenharmony_ci 503425bb815Sopenharmony_ci/** 504425bb815Sopenharmony_ci * Keywords with 6 characters. 505425bb815Sopenharmony_ci */ 506425bb815Sopenharmony_cistatic const keyword_string_t keywords_with_length_6[] = 507425bb815Sopenharmony_ci{ 508425bb815Sopenharmony_ci LEXER_KEYWORD ("delete", LEXER_KEYW_DELETE), 509425bb815Sopenharmony_ci LEXER_KEYWORD ("export", LEXER_KEYW_EXPORT), 510425bb815Sopenharmony_ci LEXER_KEYWORD ("import", LEXER_KEYW_IMPORT), 511425bb815Sopenharmony_ci LEXER_KEYWORD ("public", LEXER_KEYW_PUBLIC), 512425bb815Sopenharmony_ci LEXER_KEYWORD ("return", LEXER_KEYW_RETURN), 513425bb815Sopenharmony_ci LEXER_KEYWORD ("static", LEXER_KEYW_STATIC), 514425bb815Sopenharmony_ci LEXER_KEYWORD ("switch", LEXER_KEYW_SWITCH), 515425bb815Sopenharmony_ci LEXER_KEYWORD ("typeof", LEXER_KEYW_TYPEOF), 516425bb815Sopenharmony_ci}; 517425bb815Sopenharmony_ci 518425bb815Sopenharmony_ci/** 519425bb815Sopenharmony_ci * Keywords with 7 characters. 520425bb815Sopenharmony_ci */ 521425bb815Sopenharmony_cistatic const keyword_string_t keywords_with_length_7[] = 522425bb815Sopenharmony_ci{ 523425bb815Sopenharmony_ci LEXER_KEYWORD ("default", LEXER_KEYW_DEFAULT), 524425bb815Sopenharmony_ci LEXER_KEYWORD ("extends", LEXER_KEYW_EXTENDS), 525425bb815Sopenharmony_ci LEXER_KEYWORD ("finally", LEXER_KEYW_FINALLY), 526425bb815Sopenharmony_ci LEXER_KEYWORD ("package", LEXER_KEYW_PACKAGE), 527425bb815Sopenharmony_ci LEXER_KEYWORD ("private", LEXER_KEYW_PRIVATE), 528425bb815Sopenharmony_ci}; 529425bb815Sopenharmony_ci 530425bb815Sopenharmony_ci/** 531425bb815Sopenharmony_ci * Keywords with 8 characters. 532425bb815Sopenharmony_ci */ 533425bb815Sopenharmony_cistatic const keyword_string_t keywords_with_length_8[] = 534425bb815Sopenharmony_ci{ 535425bb815Sopenharmony_ci LEXER_KEYWORD ("continue", LEXER_KEYW_CONTINUE), 536425bb815Sopenharmony_ci LEXER_KEYWORD ("debugger", LEXER_KEYW_DEBUGGER), 537425bb815Sopenharmony_ci LEXER_KEYWORD ("function", LEXER_KEYW_FUNCTION), 538425bb815Sopenharmony_ci}; 539425bb815Sopenharmony_ci 540425bb815Sopenharmony_ci/** 541425bb815Sopenharmony_ci * Keywords with 9 characters. 542425bb815Sopenharmony_ci */ 543425bb815Sopenharmony_cistatic const keyword_string_t keywords_with_length_9[] = 544425bb815Sopenharmony_ci{ 545425bb815Sopenharmony_ci LEXER_KEYWORD ("arguments", LEXER_KEYW_ARGUMENTS), 546425bb815Sopenharmony_ci LEXER_KEYWORD ("interface", LEXER_KEYW_INTERFACE), 547425bb815Sopenharmony_ci LEXER_KEYWORD ("protected", LEXER_KEYW_PROTECTED), 548425bb815Sopenharmony_ci}; 549425bb815Sopenharmony_ci 550425bb815Sopenharmony_ci/** 551425bb815Sopenharmony_ci * Keywords with 10 characters. 552425bb815Sopenharmony_ci */ 553425bb815Sopenharmony_cistatic const keyword_string_t keywords_with_length_10[] = 554425bb815Sopenharmony_ci{ 555425bb815Sopenharmony_ci LEXER_KEYWORD ("implements", LEXER_KEYW_IMPLEMENTS), 556425bb815Sopenharmony_ci LEXER_KEYWORD ("instanceof", LEXER_KEYW_INSTANCEOF), 557425bb815Sopenharmony_ci}; 558425bb815Sopenharmony_ci 559425bb815Sopenharmony_ci/** 560425bb815Sopenharmony_ci * List of the keyword groups. 561425bb815Sopenharmony_ci */ 562425bb815Sopenharmony_cistatic const keyword_string_t * const keyword_strings_list[] = 563425bb815Sopenharmony_ci{ 564425bb815Sopenharmony_ci keywords_with_length_2, 565425bb815Sopenharmony_ci keywords_with_length_3, 566425bb815Sopenharmony_ci keywords_with_length_4, 567425bb815Sopenharmony_ci keywords_with_length_5, 568425bb815Sopenharmony_ci keywords_with_length_6, 569425bb815Sopenharmony_ci keywords_with_length_7, 570425bb815Sopenharmony_ci keywords_with_length_8, 571425bb815Sopenharmony_ci keywords_with_length_9, 572425bb815Sopenharmony_ci keywords_with_length_10 573425bb815Sopenharmony_ci}; 574425bb815Sopenharmony_ci 575425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (sizeof (keyword_strings_list) / sizeof (const keyword_string_t *) 576425bb815Sopenharmony_ci == (LEXER_KEYWORD_MAX_LENGTH - LEXER_KEYWORD_MIN_LENGTH) + 1, 577425bb815Sopenharmony_ci keyword_strings_list_size_must_equal_to_keyword_max_length_difference); 578425bb815Sopenharmony_ci 579425bb815Sopenharmony_ci/** 580425bb815Sopenharmony_ci * List of the keyword groups length. 581425bb815Sopenharmony_ci */ 582425bb815Sopenharmony_cistatic const uint8_t keyword_lengths_list[] = 583425bb815Sopenharmony_ci{ 584425bb815Sopenharmony_ci LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_2), 585425bb815Sopenharmony_ci LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_3), 586425bb815Sopenharmony_ci LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_4), 587425bb815Sopenharmony_ci LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_5), 588425bb815Sopenharmony_ci LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_6), 589425bb815Sopenharmony_ci LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_7), 590425bb815Sopenharmony_ci LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_8), 591425bb815Sopenharmony_ci LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_9), 592425bb815Sopenharmony_ci LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_10) 593425bb815Sopenharmony_ci}; 594425bb815Sopenharmony_ci 595425bb815Sopenharmony_ci#undef LEXER_KEYWORD 596425bb815Sopenharmony_ci#undef LEXER_KEYWORD_LIST_LENGTH 597425bb815Sopenharmony_ci 598425bb815Sopenharmony_ci/** 599425bb815Sopenharmony_ci * Flags for lexer_parse_identifier. 600425bb815Sopenharmony_ci */ 601425bb815Sopenharmony_citypedef enum 602425bb815Sopenharmony_ci{ 603425bb815Sopenharmony_ci LEXER_PARSE_NO_OPTS = 0, /**< no options */ 604425bb815Sopenharmony_ci LEXER_PARSE_CHECK_KEYWORDS = (1 << 0), /**< check keywords */ 605425bb815Sopenharmony_ci LEXER_PARSE_CHECK_START_AND_RETURN = (1 << 1), /**< check identifier start and return */ 606425bb815Sopenharmony_ci LEXER_PARSE_CHECK_PART_AND_RETURN = (1 << 2), /**< check identifier part and return */ 607425bb815Sopenharmony_ci} lexer_parse_options_t; 608425bb815Sopenharmony_ci 609425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (LEXER_FIRST_NON_RESERVED_KEYWORD < LEXER_FIRST_FUTURE_STRICT_RESERVED_WORD, 610425bb815Sopenharmony_ci lexer_first_non_reserved_keyword_must_be_before_lexer_first_future_strict_reserved_word); 611425bb815Sopenharmony_ci 612425bb815Sopenharmony_ci/** 613425bb815Sopenharmony_ci * Parse identifier. 614425bb815Sopenharmony_ci * 615425bb815Sopenharmony_ci * @return true, if an identifier is parsed, false otherwise 616425bb815Sopenharmony_ci */ 617425bb815Sopenharmony_cistatic bool 618425bb815Sopenharmony_cilexer_parse_identifier (parser_context_t *context_p, /**< context */ 619425bb815Sopenharmony_ci lexer_parse_options_t options) /**< check keywords */ 620425bb815Sopenharmony_ci{ 621425bb815Sopenharmony_ci /* Only very few identifiers contains \u escape sequences. */ 622425bb815Sopenharmony_ci const uint8_t *source_p = context_p->source_p; 623425bb815Sopenharmony_ci /* Note: newline or tab cannot be part of an identifier. */ 624425bb815Sopenharmony_ci parser_line_counter_t column = context_p->column; 625425bb815Sopenharmony_ci const uint8_t *source_end_p = context_p->source_end_p; 626425bb815Sopenharmony_ci size_t length = 0; 627425bb815Sopenharmony_ci uint8_t has_escape = false; 628425bb815Sopenharmony_ci 629425bb815Sopenharmony_ci do 630425bb815Sopenharmony_ci { 631425bb815Sopenharmony_ci if (*source_p == LIT_CHAR_BACKSLASH) 632425bb815Sopenharmony_ci { 633425bb815Sopenharmony_ci /* After a backslash an identifier must start. */ 634425bb815Sopenharmony_ci lit_code_point_t code_point = UINT32_MAX; 635425bb815Sopenharmony_ci uint32_t escape_length = 6; 636425bb815Sopenharmony_ci 637425bb815Sopenharmony_ci if (options & (LEXER_PARSE_CHECK_START_AND_RETURN | LEXER_PARSE_CHECK_PART_AND_RETURN)) 638425bb815Sopenharmony_ci { 639425bb815Sopenharmony_ci return true; 640425bb815Sopenharmony_ci } 641425bb815Sopenharmony_ci 642425bb815Sopenharmony_ci has_escape = true; 643425bb815Sopenharmony_ci 644425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 645425bb815Sopenharmony_ci if (source_p + 5 <= source_end_p && source_p[1] == LIT_CHAR_LOWERCASE_U) 646425bb815Sopenharmony_ci { 647425bb815Sopenharmony_ci if (source_p[2] == LIT_CHAR_LEFT_BRACE) 648425bb815Sopenharmony_ci { 649425bb815Sopenharmony_ci code_point = lexer_hex_in_braces_to_code_point (source_p + 3, source_end_p, &escape_length); 650425bb815Sopenharmony_ci } 651425bb815Sopenharmony_ci else if (source_p + 6 <= source_end_p) 652425bb815Sopenharmony_ci { 653425bb815Sopenharmony_ci code_point = lexer_hex_to_code_point (source_p + 2, 4); 654425bb815Sopenharmony_ci } 655425bb815Sopenharmony_ci } 656425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 657425bb815Sopenharmony_ci if (source_p + 6 <= source_end_p && source_p[1] == LIT_CHAR_LOWERCASE_U) 658425bb815Sopenharmony_ci { 659425bb815Sopenharmony_ci code_point = lexer_hex_to_code_point (source_p + 2, 4); 660425bb815Sopenharmony_ci } 661425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 662425bb815Sopenharmony_ci 663425bb815Sopenharmony_ci if (code_point == UINT32_MAX) 664425bb815Sopenharmony_ci { 665425bb815Sopenharmony_ci context_p->source_p = source_p; 666425bb815Sopenharmony_ci context_p->token.column = column; 667425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_UNICODE_ESCAPE_SEQUENCE); 668425bb815Sopenharmony_ci } 669425bb815Sopenharmony_ci 670425bb815Sopenharmony_ci if (length == 0) 671425bb815Sopenharmony_ci { 672425bb815Sopenharmony_ci if (!lit_code_point_is_identifier_start (code_point)) 673425bb815Sopenharmony_ci { 674425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_IDENTIFIER_START); 675425bb815Sopenharmony_ci } 676425bb815Sopenharmony_ci } 677425bb815Sopenharmony_ci else 678425bb815Sopenharmony_ci { 679425bb815Sopenharmony_ci if (!lit_code_point_is_identifier_part (code_point)) 680425bb815Sopenharmony_ci { 681425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_IDENTIFIER_PART); 682425bb815Sopenharmony_ci } 683425bb815Sopenharmony_ci } 684425bb815Sopenharmony_ci 685425bb815Sopenharmony_ci length += lit_code_point_get_cesu8_length (code_point); 686425bb815Sopenharmony_ci source_p += escape_length; 687425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_LC (column, escape_length); 688425bb815Sopenharmony_ci continue; 689425bb815Sopenharmony_ci } 690425bb815Sopenharmony_ci 691425bb815Sopenharmony_ci lit_code_point_t code_point = *source_p; 692425bb815Sopenharmony_ci lit_utf8_size_t utf8_length = 1, decoded_length = 1, char_count = 1; 693425bb815Sopenharmony_ci 694425bb815Sopenharmony_ci if (JERRY_UNLIKELY (code_point >= LIT_UTF8_2_BYTE_MARKER)) 695425bb815Sopenharmony_ci { 696425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 697425bb815Sopenharmony_ci utf8_length = lit_read_code_point_from_utf8 (source_p, 698425bb815Sopenharmony_ci (lit_utf8_size_t) (source_end_p - source_p), 699425bb815Sopenharmony_ci &code_point); 700425bb815Sopenharmony_ci decoded_length = utf8_length; 701425bb815Sopenharmony_ci 702425bb815Sopenharmony_ci /* Only ES2015 supports code points outside of the basic plane which can be part of an identifier. */ 703425bb815Sopenharmony_ci if ((code_point >= LIT_UTF16_HIGH_SURROGATE_MIN && code_point <= LIT_UTF16_HIGH_SURROGATE_MAX) 704425bb815Sopenharmony_ci && source_p + 3 < source_end_p) 705425bb815Sopenharmony_ci { 706425bb815Sopenharmony_ci lit_code_point_t low_surrogate; 707425bb815Sopenharmony_ci lit_read_code_point_from_utf8 (source_p + 3, 708425bb815Sopenharmony_ci (lit_utf8_size_t) (source_end_p - (source_p + 3)), 709425bb815Sopenharmony_ci &low_surrogate); 710425bb815Sopenharmony_ci 711425bb815Sopenharmony_ci if (low_surrogate >= LIT_UTF16_LOW_SURROGATE_MIN && low_surrogate <= LIT_UTF16_LOW_SURROGATE_MAX) 712425bb815Sopenharmony_ci { 713425bb815Sopenharmony_ci code_point = lit_convert_surrogate_pair_to_code_point ((ecma_char_t) code_point, 714425bb815Sopenharmony_ci (ecma_char_t) low_surrogate); 715425bb815Sopenharmony_ci utf8_length = 2 * 3; 716425bb815Sopenharmony_ci decoded_length = 2 * 3; 717425bb815Sopenharmony_ci char_count = 2; 718425bb815Sopenharmony_ci } 719425bb815Sopenharmony_ci } 720425bb815Sopenharmony_ci else if (source_p[0] >= LIT_UTF8_4_BYTE_MARKER) 721425bb815Sopenharmony_ci { 722425bb815Sopenharmony_ci decoded_length = 2 * 3; 723425bb815Sopenharmony_ci has_escape = true; 724425bb815Sopenharmony_ci } 725425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 726425bb815Sopenharmony_ci if (code_point < LIT_UTF8_4_BYTE_MARKER) 727425bb815Sopenharmony_ci { 728425bb815Sopenharmony_ci utf8_length = lit_read_code_point_from_utf8 (source_p, 729425bb815Sopenharmony_ci (lit_utf8_size_t) (source_end_p - source_p), 730425bb815Sopenharmony_ci &code_point); 731425bb815Sopenharmony_ci decoded_length = utf8_length; 732425bb815Sopenharmony_ci } 733425bb815Sopenharmony_ci else 734425bb815Sopenharmony_ci { 735425bb815Sopenharmony_ci code_point = 0; 736425bb815Sopenharmony_ci } 737425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 738425bb815Sopenharmony_ci } 739425bb815Sopenharmony_ci 740425bb815Sopenharmony_ci if (length == 0) 741425bb815Sopenharmony_ci { 742425bb815Sopenharmony_ci if (JERRY_UNLIKELY (options & (LEXER_PARSE_CHECK_START_AND_RETURN | LEXER_PARSE_CHECK_PART_AND_RETURN))) 743425bb815Sopenharmony_ci { 744425bb815Sopenharmony_ci if (options & LEXER_PARSE_CHECK_START_AND_RETURN) 745425bb815Sopenharmony_ci { 746425bb815Sopenharmony_ci return lit_code_point_is_identifier_start (code_point); 747425bb815Sopenharmony_ci } 748425bb815Sopenharmony_ci else 749425bb815Sopenharmony_ci { 750425bb815Sopenharmony_ci return lit_code_point_is_identifier_part (code_point); 751425bb815Sopenharmony_ci } 752425bb815Sopenharmony_ci } 753425bb815Sopenharmony_ci 754425bb815Sopenharmony_ci if (!lit_code_point_is_identifier_start (code_point)) 755425bb815Sopenharmony_ci { 756425bb815Sopenharmony_ci return false; 757425bb815Sopenharmony_ci } 758425bb815Sopenharmony_ci } 759425bb815Sopenharmony_ci else if (!lit_code_point_is_identifier_part (code_point)) 760425bb815Sopenharmony_ci { 761425bb815Sopenharmony_ci break; 762425bb815Sopenharmony_ci } 763425bb815Sopenharmony_ci 764425bb815Sopenharmony_ci source_p += utf8_length; 765425bb815Sopenharmony_ci length += decoded_length; 766425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_LC (column, char_count); 767425bb815Sopenharmony_ci } 768425bb815Sopenharmony_ci while (source_p < source_end_p); 769425bb815Sopenharmony_ci 770425bb815Sopenharmony_ci JERRY_ASSERT (length > 0); 771425bb815Sopenharmony_ci 772425bb815Sopenharmony_ci context_p->token.type = LEXER_LITERAL; 773425bb815Sopenharmony_ci context_p->token.keyword_type = LEXER_EOS; 774425bb815Sopenharmony_ci context_p->token.lit_location.type = LEXER_IDENT_LITERAL; 775425bb815Sopenharmony_ci context_p->token.lit_location.has_escape = has_escape; 776425bb815Sopenharmony_ci 777425bb815Sopenharmony_ci context_p->token.column = context_p->column; 778425bb815Sopenharmony_ci context_p->token.lit_location.char_p = context_p->source_p; 779425bb815Sopenharmony_ci context_p->token.lit_location.length = (prop_length_t) length; 780425bb815Sopenharmony_ci 781425bb815Sopenharmony_ci if (JERRY_UNLIKELY (length > PARSER_MAXIMUM_IDENT_LENGTH)) 782425bb815Sopenharmony_ci { 783425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_TOO_LONG); 784425bb815Sopenharmony_ci } 785425bb815Sopenharmony_ci 786425bb815Sopenharmony_ci /* Check keywords. */ 787425bb815Sopenharmony_ci if ((options & LEXER_PARSE_CHECK_KEYWORDS) 788425bb815Sopenharmony_ci && (length >= LEXER_KEYWORD_MIN_LENGTH && length <= LEXER_KEYWORD_MAX_LENGTH)) 789425bb815Sopenharmony_ci { 790425bb815Sopenharmony_ci const uint8_t *ident_start_p = context_p->source_p; 791425bb815Sopenharmony_ci uint8_t buffer_p[LEXER_KEYWORD_MAX_LENGTH]; 792425bb815Sopenharmony_ci 793425bb815Sopenharmony_ci if (JERRY_UNLIKELY (context_p->token.lit_location.has_escape)) 794425bb815Sopenharmony_ci { 795425bb815Sopenharmony_ci lexer_convert_ident_to_cesu8 (buffer_p, ident_start_p, (prop_length_t) length); 796425bb815Sopenharmony_ci ident_start_p = buffer_p; 797425bb815Sopenharmony_ci } 798425bb815Sopenharmony_ci 799425bb815Sopenharmony_ci const keyword_string_t *keyword_list_p = keyword_strings_list[length - LEXER_KEYWORD_MIN_LENGTH]; 800425bb815Sopenharmony_ci 801425bb815Sopenharmony_ci int start = 0; 802425bb815Sopenharmony_ci int end = keyword_lengths_list[length - LEXER_KEYWORD_MIN_LENGTH]; 803425bb815Sopenharmony_ci int middle = end / 2; 804425bb815Sopenharmony_ci 805425bb815Sopenharmony_ci do 806425bb815Sopenharmony_ci { 807425bb815Sopenharmony_ci const keyword_string_t *keyword_p = keyword_list_p + middle; 808425bb815Sopenharmony_ci int compare_result = ident_start_p[0] - keyword_p->keyword_p[0]; 809425bb815Sopenharmony_ci 810425bb815Sopenharmony_ci if (compare_result == 0) 811425bb815Sopenharmony_ci { 812425bb815Sopenharmony_ci compare_result = memcmp (ident_start_p, keyword_p->keyword_p, length); 813425bb815Sopenharmony_ci 814425bb815Sopenharmony_ci if (compare_result == 0) 815425bb815Sopenharmony_ci { 816425bb815Sopenharmony_ci context_p->token.keyword_type = (uint8_t) keyword_p->type; 817425bb815Sopenharmony_ci 818425bb815Sopenharmony_ci if (JERRY_LIKELY (keyword_p->type < LEXER_FIRST_NON_RESERVED_KEYWORD)) 819425bb815Sopenharmony_ci { 820425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 821425bb815Sopenharmony_ci if (JERRY_UNLIKELY (keyword_p->type == LEXER_KEYW_AWAIT)) 822425bb815Sopenharmony_ci { 823425bb815Sopenharmony_ci if (!(context_p->status_flags & PARSER_IS_ASYNC_FUNCTION) 824425bb815Sopenharmony_ci && !(context_p->global_status_flags & ECMA_PARSE_MODULE)) 825425bb815Sopenharmony_ci { 826425bb815Sopenharmony_ci break; 827425bb815Sopenharmony_ci } 828425bb815Sopenharmony_ci 829425bb815Sopenharmony_ci if (context_p->status_flags & PARSER_DISALLOW_AWAIT_YIELD) 830425bb815Sopenharmony_ci { 831425bb815Sopenharmony_ci if (ident_start_p == buffer_p) 832425bb815Sopenharmony_ci { 833425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD); 834425bb815Sopenharmony_ci } 835425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_AWAIT_NOT_ALLOWED); 836425bb815Sopenharmony_ci } 837425bb815Sopenharmony_ci 838425bb815Sopenharmony_ci context_p->token.type = (uint8_t) LEXER_KEYW_AWAIT; 839425bb815Sopenharmony_ci break; 840425bb815Sopenharmony_ci } 841425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 842425bb815Sopenharmony_ci 843425bb815Sopenharmony_ci if (ident_start_p == buffer_p) 844425bb815Sopenharmony_ci { 845425bb815Sopenharmony_ci /* Escape sequences are not allowed in a keyword. */ 846425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD); 847425bb815Sopenharmony_ci } 848425bb815Sopenharmony_ci 849425bb815Sopenharmony_ci context_p->token.type = (uint8_t) keyword_p->type; 850425bb815Sopenharmony_ci break; 851425bb815Sopenharmony_ci } 852425bb815Sopenharmony_ci 853425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 854425bb815Sopenharmony_ci if (keyword_p->type == LEXER_KEYW_LET && (context_p->status_flags & PARSER_IS_STRICT)) 855425bb815Sopenharmony_ci { 856425bb815Sopenharmony_ci if (ident_start_p == buffer_p) 857425bb815Sopenharmony_ci { 858425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD); 859425bb815Sopenharmony_ci } 860425bb815Sopenharmony_ci 861425bb815Sopenharmony_ci context_p->token.type = (uint8_t) LEXER_KEYW_LET; 862425bb815Sopenharmony_ci break; 863425bb815Sopenharmony_ci } 864425bb815Sopenharmony_ci 865425bb815Sopenharmony_ci if (keyword_p->type == LEXER_KEYW_YIELD && (context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION)) 866425bb815Sopenharmony_ci { 867425bb815Sopenharmony_ci if (context_p->status_flags & PARSER_DISALLOW_AWAIT_YIELD) 868425bb815Sopenharmony_ci { 869425bb815Sopenharmony_ci if (ident_start_p == buffer_p) 870425bb815Sopenharmony_ci { 871425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_KEYWORD); 872425bb815Sopenharmony_ci } 873425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_YIELD_NOT_ALLOWED); 874425bb815Sopenharmony_ci } 875425bb815Sopenharmony_ci 876425bb815Sopenharmony_ci context_p->token.type = (uint8_t) LEXER_KEYW_YIELD; 877425bb815Sopenharmony_ci break; 878425bb815Sopenharmony_ci } 879425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 880425bb815Sopenharmony_ci 881425bb815Sopenharmony_ci if (keyword_p->type >= LEXER_FIRST_FUTURE_STRICT_RESERVED_WORD 882425bb815Sopenharmony_ci && (context_p->status_flags & PARSER_IS_STRICT)) 883425bb815Sopenharmony_ci { 884425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_STRICT_IDENT_NOT_ALLOWED); 885425bb815Sopenharmony_ci } 886425bb815Sopenharmony_ci break; 887425bb815Sopenharmony_ci } 888425bb815Sopenharmony_ci } 889425bb815Sopenharmony_ci 890425bb815Sopenharmony_ci if (compare_result > 0) 891425bb815Sopenharmony_ci { 892425bb815Sopenharmony_ci start = middle + 1; 893425bb815Sopenharmony_ci } 894425bb815Sopenharmony_ci else 895425bb815Sopenharmony_ci { 896425bb815Sopenharmony_ci JERRY_ASSERT (compare_result < 0); 897425bb815Sopenharmony_ci end = middle; 898425bb815Sopenharmony_ci } 899425bb815Sopenharmony_ci 900425bb815Sopenharmony_ci middle = (start + end) / 2; 901425bb815Sopenharmony_ci } 902425bb815Sopenharmony_ci while (start < end); 903425bb815Sopenharmony_ci } 904425bb815Sopenharmony_ci 905425bb815Sopenharmony_ci context_p->source_p = source_p; 906425bb815Sopenharmony_ci context_p->column = column; 907425bb815Sopenharmony_ci return true; 908425bb815Sopenharmony_ci} /* lexer_parse_identifier */ 909425bb815Sopenharmony_ci 910425bb815Sopenharmony_ci/** 911425bb815Sopenharmony_ci * Parse string. 912425bb815Sopenharmony_ci */ 913425bb815Sopenharmony_civoid 914425bb815Sopenharmony_cilexer_parse_string (parser_context_t *context_p, /**< context */ 915425bb815Sopenharmony_ci lexer_string_options_t opts) /**< options */ 916425bb815Sopenharmony_ci{ 917425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 918425bb815Sopenharmony_ci int32_t raw_length_adjust = 0; 919425bb815Sopenharmony_ci#else /* ENABLED (JERRY_ES2015) */ 920425bb815Sopenharmony_ci JERRY_UNUSED (opts); 921425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 922425bb815Sopenharmony_ci 923425bb815Sopenharmony_ci uint8_t str_end_character = context_p->source_p[0]; 924425bb815Sopenharmony_ci const uint8_t *source_p = context_p->source_p + 1; 925425bb815Sopenharmony_ci const uint8_t *string_start_p = source_p; 926425bb815Sopenharmony_ci const uint8_t *source_end_p = context_p->source_end_p; 927425bb815Sopenharmony_ci parser_line_counter_t line = context_p->line; 928425bb815Sopenharmony_ci parser_line_counter_t column = (parser_line_counter_t) (context_p->column + 1); 929425bb815Sopenharmony_ci parser_line_counter_t original_line = line; 930425bb815Sopenharmony_ci parser_line_counter_t original_column = column; 931425bb815Sopenharmony_ci size_t length = 0; 932425bb815Sopenharmony_ci uint8_t has_escape = false; 933425bb815Sopenharmony_ci 934425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 935425bb815Sopenharmony_ci if (str_end_character == LIT_CHAR_RIGHT_BRACE) 936425bb815Sopenharmony_ci { 937425bb815Sopenharmony_ci str_end_character = LIT_CHAR_GRAVE_ACCENT; 938425bb815Sopenharmony_ci } 939425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 940425bb815Sopenharmony_ci 941425bb815Sopenharmony_ci while (true) 942425bb815Sopenharmony_ci { 943425bb815Sopenharmony_ci if (source_p >= source_end_p) 944425bb815Sopenharmony_ci { 945425bb815Sopenharmony_ci context_p->token.line = original_line; 946425bb815Sopenharmony_ci context_p->token.column = (parser_line_counter_t) (original_column - 1); 947425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_UNTERMINATED_STRING); 948425bb815Sopenharmony_ci } 949425bb815Sopenharmony_ci 950425bb815Sopenharmony_ci if (*source_p == str_end_character) 951425bb815Sopenharmony_ci { 952425bb815Sopenharmony_ci break; 953425bb815Sopenharmony_ci } 954425bb815Sopenharmony_ci 955425bb815Sopenharmony_ci if (*source_p == LIT_CHAR_BACKSLASH) 956425bb815Sopenharmony_ci { 957425bb815Sopenharmony_ci source_p++; 958425bb815Sopenharmony_ci column++; 959425bb815Sopenharmony_ci if (source_p >= source_end_p) 960425bb815Sopenharmony_ci { 961425bb815Sopenharmony_ci /* Will throw an unterminated string error. */ 962425bb815Sopenharmony_ci continue; 963425bb815Sopenharmony_ci } 964425bb815Sopenharmony_ci 965425bb815Sopenharmony_ci has_escape = true; 966425bb815Sopenharmony_ci 967425bb815Sopenharmony_ci /* Newline is ignored. */ 968425bb815Sopenharmony_ci if (*source_p == LIT_CHAR_CR) 969425bb815Sopenharmony_ci { 970425bb815Sopenharmony_ci source_p++; 971425bb815Sopenharmony_ci if (source_p < source_end_p 972425bb815Sopenharmony_ci && *source_p == LIT_CHAR_LF) 973425bb815Sopenharmony_ci { 974425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 975425bb815Sopenharmony_ci raw_length_adjust--; 976425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 977425bb815Sopenharmony_ci source_p++; 978425bb815Sopenharmony_ci } 979425bb815Sopenharmony_ci 980425bb815Sopenharmony_ci line++; 981425bb815Sopenharmony_ci column = 1; 982425bb815Sopenharmony_ci continue; 983425bb815Sopenharmony_ci } 984425bb815Sopenharmony_ci else if (*source_p == LIT_CHAR_LF) 985425bb815Sopenharmony_ci { 986425bb815Sopenharmony_ci source_p++; 987425bb815Sopenharmony_ci line++; 988425bb815Sopenharmony_ci column = 1; 989425bb815Sopenharmony_ci continue; 990425bb815Sopenharmony_ci } 991425bb815Sopenharmony_ci else if (*source_p == LEXER_NEWLINE_LS_PS_BYTE_1 && LEXER_NEWLINE_LS_PS_BYTE_23 (source_p)) 992425bb815Sopenharmony_ci { 993425bb815Sopenharmony_ci source_p += 3; 994425bb815Sopenharmony_ci line++; 995425bb815Sopenharmony_ci column = 1; 996425bb815Sopenharmony_ci continue; 997425bb815Sopenharmony_ci } 998425bb815Sopenharmony_ci 999425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1000425bb815Sopenharmony_ci if (opts & LEXER_STRING_RAW) 1001425bb815Sopenharmony_ci { 1002425bb815Sopenharmony_ci if ((*source_p == LIT_CHAR_GRAVE_ACCENT) || (*source_p == LIT_CHAR_BACKSLASH)) 1003425bb815Sopenharmony_ci { 1004425bb815Sopenharmony_ci source_p++; 1005425bb815Sopenharmony_ci column++; 1006425bb815Sopenharmony_ci length++; 1007425bb815Sopenharmony_ci } 1008425bb815Sopenharmony_ci continue; 1009425bb815Sopenharmony_ci } 1010425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1011425bb815Sopenharmony_ci 1012425bb815Sopenharmony_ci if (*source_p == LIT_CHAR_0 1013425bb815Sopenharmony_ci && source_p + 1 < source_end_p 1014425bb815Sopenharmony_ci && (*(source_p + 1) < LIT_CHAR_0 || *(source_p + 1) > LIT_CHAR_9)) 1015425bb815Sopenharmony_ci { 1016425bb815Sopenharmony_ci source_p++; 1017425bb815Sopenharmony_ci column++; 1018425bb815Sopenharmony_ci length++; 1019425bb815Sopenharmony_ci continue; 1020425bb815Sopenharmony_ci } 1021425bb815Sopenharmony_ci 1022425bb815Sopenharmony_ci /* Except \x, \u, and octal numbers, everything is 1023425bb815Sopenharmony_ci * converted to a character which has the same byte length. */ 1024425bb815Sopenharmony_ci if (*source_p >= LIT_CHAR_0 && *source_p <= LIT_CHAR_3) 1025425bb815Sopenharmony_ci { 1026425bb815Sopenharmony_ci if (context_p->status_flags & PARSER_IS_STRICT) 1027425bb815Sopenharmony_ci { 1028425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_OCTAL_ESCAPE_NOT_ALLOWED); 1029425bb815Sopenharmony_ci } 1030425bb815Sopenharmony_ci 1031425bb815Sopenharmony_ci source_p++; 1032425bb815Sopenharmony_ci column++; 1033425bb815Sopenharmony_ci 1034425bb815Sopenharmony_ci if (source_p < source_end_p && *source_p >= LIT_CHAR_0 && *source_p <= LIT_CHAR_7) 1035425bb815Sopenharmony_ci { 1036425bb815Sopenharmony_ci source_p++; 1037425bb815Sopenharmony_ci column++; 1038425bb815Sopenharmony_ci 1039425bb815Sopenharmony_ci if (source_p < source_end_p && *source_p >= LIT_CHAR_0 && *source_p <= LIT_CHAR_7) 1040425bb815Sopenharmony_ci { 1041425bb815Sopenharmony_ci /* Numbers >= 0x200 (0x80) requires 1042425bb815Sopenharmony_ci * two bytes for encoding in UTF-8. */ 1043425bb815Sopenharmony_ci if (source_p[-2] >= LIT_CHAR_2) 1044425bb815Sopenharmony_ci { 1045425bb815Sopenharmony_ci length++; 1046425bb815Sopenharmony_ci } 1047425bb815Sopenharmony_ci 1048425bb815Sopenharmony_ci source_p++; 1049425bb815Sopenharmony_ci column++; 1050425bb815Sopenharmony_ci } 1051425bb815Sopenharmony_ci } 1052425bb815Sopenharmony_ci 1053425bb815Sopenharmony_ci length++; 1054425bb815Sopenharmony_ci continue; 1055425bb815Sopenharmony_ci } 1056425bb815Sopenharmony_ci 1057425bb815Sopenharmony_ci if (*source_p >= LIT_CHAR_4 && *source_p <= LIT_CHAR_7) 1058425bb815Sopenharmony_ci { 1059425bb815Sopenharmony_ci if (context_p->status_flags & PARSER_IS_STRICT) 1060425bb815Sopenharmony_ci { 1061425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_OCTAL_ESCAPE_NOT_ALLOWED); 1062425bb815Sopenharmony_ci } 1063425bb815Sopenharmony_ci 1064425bb815Sopenharmony_ci source_p++; 1065425bb815Sopenharmony_ci column++; 1066425bb815Sopenharmony_ci 1067425bb815Sopenharmony_ci if (source_p < source_end_p && *source_p >= LIT_CHAR_0 && *source_p <= LIT_CHAR_7) 1068425bb815Sopenharmony_ci { 1069425bb815Sopenharmony_ci source_p++; 1070425bb815Sopenharmony_ci column++; 1071425bb815Sopenharmony_ci } 1072425bb815Sopenharmony_ci 1073425bb815Sopenharmony_ci /* The maximum number is 0x4d so the UTF-8 1074425bb815Sopenharmony_ci * representation is always one byte. */ 1075425bb815Sopenharmony_ci length++; 1076425bb815Sopenharmony_ci continue; 1077425bb815Sopenharmony_ci } 1078425bb815Sopenharmony_ci 1079425bb815Sopenharmony_ci if (*source_p == LIT_CHAR_LOWERCASE_X || *source_p == LIT_CHAR_LOWERCASE_U) 1080425bb815Sopenharmony_ci { 1081425bb815Sopenharmony_ci uint32_t escape_length = (*source_p == LIT_CHAR_LOWERCASE_X) ? 3 : 5; 1082425bb815Sopenharmony_ci lit_code_point_t code_point = UINT32_MAX; 1083425bb815Sopenharmony_ci 1084425bb815Sopenharmony_ci context_p->token.line = line; 1085425bb815Sopenharmony_ci context_p->token.column = (parser_line_counter_t) (column - 1); 1086425bb815Sopenharmony_ci 1087425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1088425bb815Sopenharmony_ci if (source_p + 4 <= source_end_p 1089425bb815Sopenharmony_ci && source_p[0] == LIT_CHAR_LOWERCASE_U 1090425bb815Sopenharmony_ci && source_p[1] == LIT_CHAR_LEFT_BRACE) 1091425bb815Sopenharmony_ci { 1092425bb815Sopenharmony_ci code_point = lexer_hex_in_braces_to_code_point (source_p + 2, source_end_p, &escape_length); 1093425bb815Sopenharmony_ci escape_length--; 1094425bb815Sopenharmony_ci } 1095425bb815Sopenharmony_ci else 1096425bb815Sopenharmony_ci { 1097425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1098425bb815Sopenharmony_ci if (source_p + escape_length <= source_end_p) 1099425bb815Sopenharmony_ci { 1100425bb815Sopenharmony_ci code_point = lexer_hex_to_code_point (source_p + 1, escape_length - 1); 1101425bb815Sopenharmony_ci } 1102425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1103425bb815Sopenharmony_ci } 1104425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1105425bb815Sopenharmony_ci 1106425bb815Sopenharmony_ci if (code_point == UINT32_MAX) 1107425bb815Sopenharmony_ci { 1108425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_UNICODE_ESCAPE_SEQUENCE); 1109425bb815Sopenharmony_ci } 1110425bb815Sopenharmony_ci 1111425bb815Sopenharmony_ci length += lit_code_point_get_cesu8_length (code_point); 1112425bb815Sopenharmony_ci 1113425bb815Sopenharmony_ci source_p += escape_length; 1114425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_LC (column, escape_length); 1115425bb815Sopenharmony_ci continue; 1116425bb815Sopenharmony_ci } 1117425bb815Sopenharmony_ci } 1118425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1119425bb815Sopenharmony_ci else if (str_end_character == LIT_CHAR_GRAVE_ACCENT && 1120425bb815Sopenharmony_ci source_p[0] == LIT_CHAR_DOLLAR_SIGN && 1121425bb815Sopenharmony_ci source_p + 1 < source_end_p && 1122425bb815Sopenharmony_ci source_p[1] == LIT_CHAR_LEFT_BRACE) 1123425bb815Sopenharmony_ci { 1124425bb815Sopenharmony_ci raw_length_adjust--; 1125425bb815Sopenharmony_ci source_p++; 1126425bb815Sopenharmony_ci break; 1127425bb815Sopenharmony_ci } 1128425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1129425bb815Sopenharmony_ci 1130425bb815Sopenharmony_ci if (*source_p >= LIT_UTF8_4_BYTE_MARKER) 1131425bb815Sopenharmony_ci { 1132425bb815Sopenharmony_ci /* Processing 4 byte unicode sequence (even if it is 1133425bb815Sopenharmony_ci * after a backslash). Always converted to two 3 byte 1134425bb815Sopenharmony_ci * long sequence. */ 1135425bb815Sopenharmony_ci length += 2 * 3; 1136425bb815Sopenharmony_ci has_escape = true; 1137425bb815Sopenharmony_ci source_p += 4; 1138425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1139425bb815Sopenharmony_ci raw_length_adjust += 2; 1140425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1141425bb815Sopenharmony_ci column++; 1142425bb815Sopenharmony_ci continue; 1143425bb815Sopenharmony_ci } 1144425bb815Sopenharmony_ci else if (*source_p == LIT_CHAR_TAB) 1145425bb815Sopenharmony_ci { 1146425bb815Sopenharmony_ci column = align_column_to_tab (column); 1147425bb815Sopenharmony_ci /* Subtract -1 because column is increased below. */ 1148425bb815Sopenharmony_ci column--; 1149425bb815Sopenharmony_ci } 1150425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1151425bb815Sopenharmony_ci else if (str_end_character == LIT_CHAR_GRAVE_ACCENT) 1152425bb815Sopenharmony_ci { 1153425bb815Sopenharmony_ci /* Newline (without backslash) is part of the string. 1154425bb815Sopenharmony_ci Note: ECMAScript v6, 11.8.6.1 <CR> or <CR><LF> are both normalized to <LF> */ 1155425bb815Sopenharmony_ci if (*source_p == LIT_CHAR_CR) 1156425bb815Sopenharmony_ci { 1157425bb815Sopenharmony_ci has_escape = true; 1158425bb815Sopenharmony_ci source_p++; 1159425bb815Sopenharmony_ci length++; 1160425bb815Sopenharmony_ci if (source_p < source_end_p 1161425bb815Sopenharmony_ci && *source_p == LIT_CHAR_LF) 1162425bb815Sopenharmony_ci { 1163425bb815Sopenharmony_ci source_p++; 1164425bb815Sopenharmony_ci raw_length_adjust--; 1165425bb815Sopenharmony_ci } 1166425bb815Sopenharmony_ci line++; 1167425bb815Sopenharmony_ci column = 1; 1168425bb815Sopenharmony_ci continue; 1169425bb815Sopenharmony_ci } 1170425bb815Sopenharmony_ci else if (*source_p == LIT_CHAR_LF) 1171425bb815Sopenharmony_ci { 1172425bb815Sopenharmony_ci source_p++; 1173425bb815Sopenharmony_ci length++; 1174425bb815Sopenharmony_ci line++; 1175425bb815Sopenharmony_ci column = 1; 1176425bb815Sopenharmony_ci continue; 1177425bb815Sopenharmony_ci } 1178425bb815Sopenharmony_ci else if (*source_p == LEXER_NEWLINE_LS_PS_BYTE_1 && LEXER_NEWLINE_LS_PS_BYTE_23 (source_p)) 1179425bb815Sopenharmony_ci { 1180425bb815Sopenharmony_ci source_p += 3; 1181425bb815Sopenharmony_ci length += 3; 1182425bb815Sopenharmony_ci line++; 1183425bb815Sopenharmony_ci column = 1; 1184425bb815Sopenharmony_ci continue; 1185425bb815Sopenharmony_ci } 1186425bb815Sopenharmony_ci } 1187425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1188425bb815Sopenharmony_ci else if (*source_p == LIT_CHAR_CR 1189425bb815Sopenharmony_ci || *source_p == LIT_CHAR_LF 1190425bb815Sopenharmony_ci || (*source_p == LEXER_NEWLINE_LS_PS_BYTE_1 && LEXER_NEWLINE_LS_PS_BYTE_23 (source_p))) 1191425bb815Sopenharmony_ci { 1192425bb815Sopenharmony_ci context_p->token.line = line; 1193425bb815Sopenharmony_ci context_p->token.column = column; 1194425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_NEWLINE_NOT_ALLOWED); 1195425bb815Sopenharmony_ci } 1196425bb815Sopenharmony_ci 1197425bb815Sopenharmony_ci source_p++; 1198425bb815Sopenharmony_ci column++; 1199425bb815Sopenharmony_ci length++; 1200425bb815Sopenharmony_ci 1201425bb815Sopenharmony_ci while (source_p < source_end_p 1202425bb815Sopenharmony_ci && IS_UTF8_INTERMEDIATE_OCTET (*source_p)) 1203425bb815Sopenharmony_ci { 1204425bb815Sopenharmony_ci source_p++; 1205425bb815Sopenharmony_ci length++; 1206425bb815Sopenharmony_ci } 1207425bb815Sopenharmony_ci } 1208425bb815Sopenharmony_ci 1209425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1210425bb815Sopenharmony_ci if (opts & LEXER_STRING_RAW) 1211425bb815Sopenharmony_ci { 1212425bb815Sopenharmony_ci length = (size_t) ((source_p - string_start_p) + raw_length_adjust); 1213425bb815Sopenharmony_ci } 1214425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1215425bb815Sopenharmony_ci 1216425bb815Sopenharmony_ci if (length > PARSER_MAXIMUM_STRING_LENGTH) 1217425bb815Sopenharmony_ci { 1218425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_STRING_TOO_LONG); 1219425bb815Sopenharmony_ci } 1220425bb815Sopenharmony_ci 1221425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1222425bb815Sopenharmony_ci context_p->token.type = ((str_end_character != LIT_CHAR_GRAVE_ACCENT) ? LEXER_LITERAL 1223425bb815Sopenharmony_ci : LEXER_TEMPLATE_LITERAL); 1224425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 1225425bb815Sopenharmony_ci context_p->token.type = LEXER_LITERAL; 1226425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1227425bb815Sopenharmony_ci 1228425bb815Sopenharmony_ci /* Fill literal data. */ 1229425bb815Sopenharmony_ci context_p->token.lit_location.char_p = string_start_p; 1230425bb815Sopenharmony_ci context_p->token.lit_location.length = (prop_length_t) length; 1231425bb815Sopenharmony_ci context_p->token.lit_location.type = LEXER_STRING_LITERAL; 1232425bb815Sopenharmony_ci context_p->token.lit_location.has_escape = has_escape; 1233425bb815Sopenharmony_ci 1234425bb815Sopenharmony_ci context_p->source_p = source_p + 1; 1235425bb815Sopenharmony_ci context_p->line = line; 1236425bb815Sopenharmony_ci context_p->column = (parser_line_counter_t) (column + 1); 1237425bb815Sopenharmony_ci} /* lexer_parse_string */ 1238425bb815Sopenharmony_ci 1239425bb815Sopenharmony_ci/** 1240425bb815Sopenharmony_ci * Parse octal number. 1241425bb815Sopenharmony_ci */ 1242425bb815Sopenharmony_cistatic inline void 1243425bb815Sopenharmony_cilexer_parse_octal_number (parser_context_t *context_p, /** context */ 1244425bb815Sopenharmony_ci const uint8_t **source_p) /**< current source position */ 1245425bb815Sopenharmony_ci{ 1246425bb815Sopenharmony_ci do 1247425bb815Sopenharmony_ci { 1248425bb815Sopenharmony_ci (*source_p)++; 1249425bb815Sopenharmony_ci } 1250425bb815Sopenharmony_ci while (*source_p < context_p->source_end_p 1251425bb815Sopenharmony_ci && *source_p[0] >= LIT_CHAR_0 1252425bb815Sopenharmony_ci && *source_p[0] <= LIT_CHAR_7); 1253425bb815Sopenharmony_ci 1254425bb815Sopenharmony_ci if (*source_p < context_p->source_end_p 1255425bb815Sopenharmony_ci && (*source_p[0] == LIT_CHAR_8 || *source_p[0] == LIT_CHAR_9)) 1256425bb815Sopenharmony_ci { 1257425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_OCTAL_DIGIT); 1258425bb815Sopenharmony_ci } 1259425bb815Sopenharmony_ci} /* lexer_parse_octal_number */ 1260425bb815Sopenharmony_ci 1261425bb815Sopenharmony_ci/** 1262425bb815Sopenharmony_ci * Parse number. 1263425bb815Sopenharmony_ci */ 1264425bb815Sopenharmony_cistatic void 1265425bb815Sopenharmony_cilexer_parse_number (parser_context_t *context_p) /**< context */ 1266425bb815Sopenharmony_ci{ 1267425bb815Sopenharmony_ci const uint8_t *source_p = context_p->source_p; 1268425bb815Sopenharmony_ci const uint8_t *source_end_p = context_p->source_end_p; 1269425bb815Sopenharmony_ci bool can_be_float = false; 1270425bb815Sopenharmony_ci size_t length; 1271425bb815Sopenharmony_ci 1272425bb815Sopenharmony_ci context_p->token.type = LEXER_LITERAL; 1273425bb815Sopenharmony_ci context_p->token.keyword_type = LEXER_EOS; 1274425bb815Sopenharmony_ci context_p->token.extra_value = LEXER_NUMBER_DECIMAL; 1275425bb815Sopenharmony_ci context_p->token.lit_location.char_p = source_p; 1276425bb815Sopenharmony_ci context_p->token.lit_location.type = LEXER_NUMBER_LITERAL; 1277425bb815Sopenharmony_ci context_p->token.lit_location.has_escape = false; 1278425bb815Sopenharmony_ci 1279425bb815Sopenharmony_ci if (source_p[0] == LIT_CHAR_0 1280425bb815Sopenharmony_ci && source_p + 1 < source_end_p) 1281425bb815Sopenharmony_ci { 1282425bb815Sopenharmony_ci if (LEXER_TO_ASCII_LOWERCASE (source_p[1]) == LIT_CHAR_LOWERCASE_X) 1283425bb815Sopenharmony_ci { 1284425bb815Sopenharmony_ci context_p->token.extra_value = LEXER_NUMBER_HEXADECIMAL; 1285425bb815Sopenharmony_ci source_p += 2; 1286425bb815Sopenharmony_ci 1287425bb815Sopenharmony_ci if (source_p >= source_end_p 1288425bb815Sopenharmony_ci || !lit_char_is_hex_digit (source_p[0])) 1289425bb815Sopenharmony_ci { 1290425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_HEX_DIGIT); 1291425bb815Sopenharmony_ci } 1292425bb815Sopenharmony_ci 1293425bb815Sopenharmony_ci do 1294425bb815Sopenharmony_ci { 1295425bb815Sopenharmony_ci source_p++; 1296425bb815Sopenharmony_ci } 1297425bb815Sopenharmony_ci while (source_p < source_end_p 1298425bb815Sopenharmony_ci && lit_char_is_hex_digit (source_p[0])); 1299425bb815Sopenharmony_ci } 1300425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1301425bb815Sopenharmony_ci else if (LEXER_TO_ASCII_LOWERCASE (source_p[1]) == LIT_CHAR_LOWERCASE_O) 1302425bb815Sopenharmony_ci { 1303425bb815Sopenharmony_ci context_p->token.extra_value = LEXER_NUMBER_OCTAL; 1304425bb815Sopenharmony_ci context_p->token.lit_location.char_p++; 1305425bb815Sopenharmony_ci context_p->source_p++; 1306425bb815Sopenharmony_ci source_p += 2; 1307425bb815Sopenharmony_ci 1308425bb815Sopenharmony_ci if (source_p >= source_end_p 1309425bb815Sopenharmony_ci || !lit_char_is_octal_digit (source_p[0])) 1310425bb815Sopenharmony_ci { 1311425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_OCTAL_DIGIT); 1312425bb815Sopenharmony_ci } 1313425bb815Sopenharmony_ci 1314425bb815Sopenharmony_ci lexer_parse_octal_number (context_p, &source_p); 1315425bb815Sopenharmony_ci } 1316425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1317425bb815Sopenharmony_ci else if (source_p[1] >= LIT_CHAR_0 1318425bb815Sopenharmony_ci && source_p[1] <= LIT_CHAR_7) 1319425bb815Sopenharmony_ci { 1320425bb815Sopenharmony_ci context_p->token.extra_value = LEXER_NUMBER_OCTAL; 1321425bb815Sopenharmony_ci 1322425bb815Sopenharmony_ci if (context_p->status_flags & PARSER_IS_STRICT) 1323425bb815Sopenharmony_ci { 1324425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_OCTAL_NUMBER_NOT_ALLOWED); 1325425bb815Sopenharmony_ci } 1326425bb815Sopenharmony_ci 1327425bb815Sopenharmony_ci lexer_parse_octal_number (context_p, &source_p); 1328425bb815Sopenharmony_ci } 1329425bb815Sopenharmony_ci else if (source_p[1] >= LIT_CHAR_8 1330425bb815Sopenharmony_ci && source_p[1] <= LIT_CHAR_9) 1331425bb815Sopenharmony_ci { 1332425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_NUMBER); 1333425bb815Sopenharmony_ci } 1334425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1335425bb815Sopenharmony_ci else if (LEXER_TO_ASCII_LOWERCASE (source_p[1]) == LIT_CHAR_LOWERCASE_B) 1336425bb815Sopenharmony_ci { 1337425bb815Sopenharmony_ci context_p->token.extra_value = LEXER_NUMBER_BINARY; 1338425bb815Sopenharmony_ci context_p->token.lit_location.char_p++; 1339425bb815Sopenharmony_ci context_p->source_p++; 1340425bb815Sopenharmony_ci source_p += 2; 1341425bb815Sopenharmony_ci 1342425bb815Sopenharmony_ci if (source_p >= source_end_p 1343425bb815Sopenharmony_ci || !lit_char_is_binary_digit (source_p[0])) 1344425bb815Sopenharmony_ci { 1345425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_BIN_DIGIT); 1346425bb815Sopenharmony_ci } 1347425bb815Sopenharmony_ci 1348425bb815Sopenharmony_ci do 1349425bb815Sopenharmony_ci { 1350425bb815Sopenharmony_ci source_p++; 1351425bb815Sopenharmony_ci } 1352425bb815Sopenharmony_ci while (source_p < source_end_p 1353425bb815Sopenharmony_ci && lit_char_is_binary_digit (source_p[0])); 1354425bb815Sopenharmony_ci } 1355425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1356425bb815Sopenharmony_ci else 1357425bb815Sopenharmony_ci { 1358425bb815Sopenharmony_ci can_be_float = true; 1359425bb815Sopenharmony_ci source_p++; 1360425bb815Sopenharmony_ci } 1361425bb815Sopenharmony_ci } 1362425bb815Sopenharmony_ci else 1363425bb815Sopenharmony_ci { 1364425bb815Sopenharmony_ci while (source_p < source_end_p 1365425bb815Sopenharmony_ci && source_p[0] >= LIT_CHAR_0 1366425bb815Sopenharmony_ci && source_p[0] <= LIT_CHAR_9) 1367425bb815Sopenharmony_ci { 1368425bb815Sopenharmony_ci source_p++; 1369425bb815Sopenharmony_ci } 1370425bb815Sopenharmony_ci 1371425bb815Sopenharmony_ci can_be_float = true; 1372425bb815Sopenharmony_ci } 1373425bb815Sopenharmony_ci 1374425bb815Sopenharmony_ci if (can_be_float) 1375425bb815Sopenharmony_ci { 1376425bb815Sopenharmony_ci if (source_p < source_end_p 1377425bb815Sopenharmony_ci && source_p[0] == LIT_CHAR_DOT) 1378425bb815Sopenharmony_ci { 1379425bb815Sopenharmony_ci source_p++; 1380425bb815Sopenharmony_ci while (source_p < source_end_p 1381425bb815Sopenharmony_ci && source_p[0] >= LIT_CHAR_0 1382425bb815Sopenharmony_ci && source_p[0] <= LIT_CHAR_9) 1383425bb815Sopenharmony_ci { 1384425bb815Sopenharmony_ci source_p++; 1385425bb815Sopenharmony_ci } 1386425bb815Sopenharmony_ci } 1387425bb815Sopenharmony_ci 1388425bb815Sopenharmony_ci if (source_p < source_end_p 1389425bb815Sopenharmony_ci && LEXER_TO_ASCII_LOWERCASE (source_p[0]) == LIT_CHAR_LOWERCASE_E) 1390425bb815Sopenharmony_ci { 1391425bb815Sopenharmony_ci source_p++; 1392425bb815Sopenharmony_ci 1393425bb815Sopenharmony_ci if (source_p < source_end_p 1394425bb815Sopenharmony_ci && (source_p[0] == LIT_CHAR_PLUS || source_p[0] == LIT_CHAR_MINUS)) 1395425bb815Sopenharmony_ci { 1396425bb815Sopenharmony_ci source_p++; 1397425bb815Sopenharmony_ci } 1398425bb815Sopenharmony_ci 1399425bb815Sopenharmony_ci if (source_p >= source_end_p 1400425bb815Sopenharmony_ci || source_p[0] < LIT_CHAR_0 1401425bb815Sopenharmony_ci || source_p[0] > LIT_CHAR_9) 1402425bb815Sopenharmony_ci { 1403425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_MISSING_EXPONENT); 1404425bb815Sopenharmony_ci } 1405425bb815Sopenharmony_ci 1406425bb815Sopenharmony_ci do 1407425bb815Sopenharmony_ci { 1408425bb815Sopenharmony_ci source_p++; 1409425bb815Sopenharmony_ci } 1410425bb815Sopenharmony_ci while (source_p < source_end_p 1411425bb815Sopenharmony_ci && source_p[0] >= LIT_CHAR_0 1412425bb815Sopenharmony_ci && source_p[0] <= LIT_CHAR_9); 1413425bb815Sopenharmony_ci } 1414425bb815Sopenharmony_ci } 1415425bb815Sopenharmony_ci 1416425bb815Sopenharmony_ci length = (size_t) (source_p - context_p->source_p); 1417425bb815Sopenharmony_ci if (length > PARSER_MAXIMUM_IDENT_LENGTH) 1418425bb815Sopenharmony_ci { 1419425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_NUMBER_TOO_LONG); 1420425bb815Sopenharmony_ci } 1421425bb815Sopenharmony_ci 1422425bb815Sopenharmony_ci context_p->token.lit_location.length = (prop_length_t) length; 1423425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_LC (context_p->column, length); 1424425bb815Sopenharmony_ci context_p->source_p = source_p; 1425425bb815Sopenharmony_ci 1426425bb815Sopenharmony_ci if (source_p < source_end_p && lexer_parse_identifier (context_p, LEXER_PARSE_CHECK_START_AND_RETURN)) 1427425bb815Sopenharmony_ci { 1428425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_AFTER_NUMBER); 1429425bb815Sopenharmony_ci } 1430425bb815Sopenharmony_ci} /* lexer_parse_number */ 1431425bb815Sopenharmony_ci 1432425bb815Sopenharmony_ci/** 1433425bb815Sopenharmony_ci * One character long token (e.g. comma). 1434425bb815Sopenharmony_ci * 1435425bb815Sopenharmony_ci * @param char1 character 1436425bb815Sopenharmony_ci * @param type1 type 1437425bb815Sopenharmony_ci */ 1438425bb815Sopenharmony_ci#define LEXER_TYPE_A_TOKEN(char1, type1) \ 1439425bb815Sopenharmony_ci case (uint8_t) (char1): \ 1440425bb815Sopenharmony_ci { \ 1441425bb815Sopenharmony_ci context_p->token.type = (type1); \ 1442425bb815Sopenharmony_ci length = 1; \ 1443425bb815Sopenharmony_ci break; \ 1444425bb815Sopenharmony_ci } 1445425bb815Sopenharmony_ci 1446425bb815Sopenharmony_ci/** 1447425bb815Sopenharmony_ci * Token pair, where the first token is prefix of the second (e.g. % and %=). 1448425bb815Sopenharmony_ci * 1449425bb815Sopenharmony_ci * @param char1 first character 1450425bb815Sopenharmony_ci * @param type1 type of the first character 1451425bb815Sopenharmony_ci * @param char2 second character 1452425bb815Sopenharmony_ci * @param type2 type of the second character 1453425bb815Sopenharmony_ci */ 1454425bb815Sopenharmony_ci#define LEXER_TYPE_B_TOKEN(char1, type1, char2, type2) \ 1455425bb815Sopenharmony_ci case (uint8_t) (char1): \ 1456425bb815Sopenharmony_ci { \ 1457425bb815Sopenharmony_ci if (length >= 2 && context_p->source_p[1] == (uint8_t) (char2)) \ 1458425bb815Sopenharmony_ci { \ 1459425bb815Sopenharmony_ci context_p->token.type = (type2); \ 1460425bb815Sopenharmony_ci length = 2; \ 1461425bb815Sopenharmony_ci break; \ 1462425bb815Sopenharmony_ci } \ 1463425bb815Sopenharmony_ci \ 1464425bb815Sopenharmony_ci context_p->token.type = (type1); \ 1465425bb815Sopenharmony_ci length = 1; \ 1466425bb815Sopenharmony_ci break; \ 1467425bb815Sopenharmony_ci } 1468425bb815Sopenharmony_ci 1469425bb815Sopenharmony_ci/** 1470425bb815Sopenharmony_ci * Three tokens, where the first is the prefix of the other two (e.g. &, &&, &=). 1471425bb815Sopenharmony_ci * 1472425bb815Sopenharmony_ci * @param char1 first character 1473425bb815Sopenharmony_ci * @param type1 type of the first character 1474425bb815Sopenharmony_ci * @param char2 second character 1475425bb815Sopenharmony_ci * @param type2 type of the second character 1476425bb815Sopenharmony_ci * @param char3 third character 1477425bb815Sopenharmony_ci * @param type3 type of the third character 1478425bb815Sopenharmony_ci */ 1479425bb815Sopenharmony_ci#define LEXER_TYPE_C_TOKEN(char1, type1, char2, type2, char3, type3) \ 1480425bb815Sopenharmony_ci case (uint8_t) (char1): \ 1481425bb815Sopenharmony_ci { \ 1482425bb815Sopenharmony_ci if (length >= 2) \ 1483425bb815Sopenharmony_ci { \ 1484425bb815Sopenharmony_ci if (context_p->source_p[1] == (uint8_t) (char2)) \ 1485425bb815Sopenharmony_ci { \ 1486425bb815Sopenharmony_ci context_p->token.type = (type2); \ 1487425bb815Sopenharmony_ci length = 2; \ 1488425bb815Sopenharmony_ci break; \ 1489425bb815Sopenharmony_ci } \ 1490425bb815Sopenharmony_ci \ 1491425bb815Sopenharmony_ci if (context_p->source_p[1] == (uint8_t) (char3)) \ 1492425bb815Sopenharmony_ci { \ 1493425bb815Sopenharmony_ci context_p->token.type = (type3); \ 1494425bb815Sopenharmony_ci length = 2; \ 1495425bb815Sopenharmony_ci break; \ 1496425bb815Sopenharmony_ci } \ 1497425bb815Sopenharmony_ci } \ 1498425bb815Sopenharmony_ci \ 1499425bb815Sopenharmony_ci context_p->token.type = (type1); \ 1500425bb815Sopenharmony_ci length = 1; \ 1501425bb815Sopenharmony_ci break; \ 1502425bb815Sopenharmony_ci } 1503425bb815Sopenharmony_ci 1504425bb815Sopenharmony_ci/** 1505425bb815Sopenharmony_ci * Get next token. 1506425bb815Sopenharmony_ci */ 1507425bb815Sopenharmony_civoid 1508425bb815Sopenharmony_cilexer_next_token (parser_context_t *context_p) /**< context */ 1509425bb815Sopenharmony_ci{ 1510425bb815Sopenharmony_ci size_t length; 1511425bb815Sopenharmony_ci 1512425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 1513425bb815Sopenharmony_ci 1514425bb815Sopenharmony_ci context_p->token.line = context_p->line; 1515425bb815Sopenharmony_ci context_p->token.column = context_p->column; 1516425bb815Sopenharmony_ci 1517425bb815Sopenharmony_ci length = (size_t) (context_p->source_end_p - context_p->source_p); 1518425bb815Sopenharmony_ci if (length == 0) 1519425bb815Sopenharmony_ci { 1520425bb815Sopenharmony_ci context_p->token.type = LEXER_EOS; 1521425bb815Sopenharmony_ci return; 1522425bb815Sopenharmony_ci } 1523425bb815Sopenharmony_ci 1524425bb815Sopenharmony_ci if (lexer_parse_identifier (context_p, LEXER_PARSE_CHECK_KEYWORDS)) 1525425bb815Sopenharmony_ci { 1526425bb815Sopenharmony_ci return; 1527425bb815Sopenharmony_ci } 1528425bb815Sopenharmony_ci 1529425bb815Sopenharmony_ci if (context_p->source_p[0] >= LIT_CHAR_0 && context_p->source_p[0] <= LIT_CHAR_9) 1530425bb815Sopenharmony_ci { 1531425bb815Sopenharmony_ci lexer_parse_number (context_p); 1532425bb815Sopenharmony_ci return; 1533425bb815Sopenharmony_ci } 1534425bb815Sopenharmony_ci 1535425bb815Sopenharmony_ci switch (context_p->source_p[0]) 1536425bb815Sopenharmony_ci { 1537425bb815Sopenharmony_ci LEXER_TYPE_A_TOKEN (LIT_CHAR_LEFT_BRACE, LEXER_LEFT_BRACE); 1538425bb815Sopenharmony_ci LEXER_TYPE_A_TOKEN (LIT_CHAR_LEFT_PAREN, LEXER_LEFT_PAREN); 1539425bb815Sopenharmony_ci LEXER_TYPE_A_TOKEN (LIT_CHAR_LEFT_SQUARE, LEXER_LEFT_SQUARE); 1540425bb815Sopenharmony_ci LEXER_TYPE_A_TOKEN (LIT_CHAR_RIGHT_BRACE, LEXER_RIGHT_BRACE); 1541425bb815Sopenharmony_ci LEXER_TYPE_A_TOKEN (LIT_CHAR_RIGHT_PAREN, LEXER_RIGHT_PAREN); 1542425bb815Sopenharmony_ci LEXER_TYPE_A_TOKEN (LIT_CHAR_RIGHT_SQUARE, LEXER_RIGHT_SQUARE); 1543425bb815Sopenharmony_ci LEXER_TYPE_A_TOKEN (LIT_CHAR_SEMICOLON, LEXER_SEMICOLON); 1544425bb815Sopenharmony_ci LEXER_TYPE_A_TOKEN (LIT_CHAR_COMMA, LEXER_COMMA); 1545425bb815Sopenharmony_ci 1546425bb815Sopenharmony_ci case (uint8_t) LIT_CHAR_DOT: 1547425bb815Sopenharmony_ci { 1548425bb815Sopenharmony_ci if (length >= 2 1549425bb815Sopenharmony_ci && (context_p->source_p[1] >= LIT_CHAR_0 && context_p->source_p[1] <= LIT_CHAR_9)) 1550425bb815Sopenharmony_ci { 1551425bb815Sopenharmony_ci lexer_parse_number (context_p); 1552425bb815Sopenharmony_ci return; 1553425bb815Sopenharmony_ci } 1554425bb815Sopenharmony_ci 1555425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1556425bb815Sopenharmony_ci if (length >= 3 1557425bb815Sopenharmony_ci && context_p->source_p[1] == LIT_CHAR_DOT 1558425bb815Sopenharmony_ci && context_p->source_p[2] == LIT_CHAR_DOT) 1559425bb815Sopenharmony_ci { 1560425bb815Sopenharmony_ci context_p->token.type = LEXER_THREE_DOTS; 1561425bb815Sopenharmony_ci length = 3; 1562425bb815Sopenharmony_ci break; 1563425bb815Sopenharmony_ci } 1564425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1565425bb815Sopenharmony_ci 1566425bb815Sopenharmony_ci context_p->token.type = LEXER_DOT; 1567425bb815Sopenharmony_ci length = 1; 1568425bb815Sopenharmony_ci break; 1569425bb815Sopenharmony_ci } 1570425bb815Sopenharmony_ci 1571425bb815Sopenharmony_ci case (uint8_t) LIT_CHAR_LESS_THAN: 1572425bb815Sopenharmony_ci { 1573425bb815Sopenharmony_ci if (length >= 2) 1574425bb815Sopenharmony_ci { 1575425bb815Sopenharmony_ci if (context_p->source_p[1] == (uint8_t) LIT_CHAR_EQUALS) 1576425bb815Sopenharmony_ci { 1577425bb815Sopenharmony_ci context_p->token.type = LEXER_LESS_EQUAL; 1578425bb815Sopenharmony_ci length = 2; 1579425bb815Sopenharmony_ci break; 1580425bb815Sopenharmony_ci } 1581425bb815Sopenharmony_ci 1582425bb815Sopenharmony_ci if (context_p->source_p[1] == (uint8_t) LIT_CHAR_LESS_THAN) 1583425bb815Sopenharmony_ci { 1584425bb815Sopenharmony_ci if (length >= 3 && context_p->source_p[2] == (uint8_t) LIT_CHAR_EQUALS) 1585425bb815Sopenharmony_ci { 1586425bb815Sopenharmony_ci context_p->token.type = LEXER_ASSIGN_LEFT_SHIFT; 1587425bb815Sopenharmony_ci length = 3; 1588425bb815Sopenharmony_ci break; 1589425bb815Sopenharmony_ci } 1590425bb815Sopenharmony_ci 1591425bb815Sopenharmony_ci context_p->token.type = LEXER_LEFT_SHIFT; 1592425bb815Sopenharmony_ci length = 2; 1593425bb815Sopenharmony_ci break; 1594425bb815Sopenharmony_ci } 1595425bb815Sopenharmony_ci } 1596425bb815Sopenharmony_ci 1597425bb815Sopenharmony_ci context_p->token.type = LEXER_LESS; 1598425bb815Sopenharmony_ci length = 1; 1599425bb815Sopenharmony_ci break; 1600425bb815Sopenharmony_ci } 1601425bb815Sopenharmony_ci 1602425bb815Sopenharmony_ci case (uint8_t) LIT_CHAR_GREATER_THAN: 1603425bb815Sopenharmony_ci { 1604425bb815Sopenharmony_ci if (length >= 2) 1605425bb815Sopenharmony_ci { 1606425bb815Sopenharmony_ci if (context_p->source_p[1] == (uint8_t) LIT_CHAR_EQUALS) 1607425bb815Sopenharmony_ci { 1608425bb815Sopenharmony_ci context_p->token.type = LEXER_GREATER_EQUAL; 1609425bb815Sopenharmony_ci length = 2; 1610425bb815Sopenharmony_ci break; 1611425bb815Sopenharmony_ci } 1612425bb815Sopenharmony_ci 1613425bb815Sopenharmony_ci if (context_p->source_p[1] == (uint8_t) LIT_CHAR_GREATER_THAN) 1614425bb815Sopenharmony_ci { 1615425bb815Sopenharmony_ci if (length >= 3) 1616425bb815Sopenharmony_ci { 1617425bb815Sopenharmony_ci if (context_p->source_p[2] == (uint8_t) LIT_CHAR_EQUALS) 1618425bb815Sopenharmony_ci { 1619425bb815Sopenharmony_ci context_p->token.type = LEXER_ASSIGN_RIGHT_SHIFT; 1620425bb815Sopenharmony_ci length = 3; 1621425bb815Sopenharmony_ci break; 1622425bb815Sopenharmony_ci } 1623425bb815Sopenharmony_ci 1624425bb815Sopenharmony_ci if (context_p->source_p[2] == (uint8_t) LIT_CHAR_GREATER_THAN) 1625425bb815Sopenharmony_ci { 1626425bb815Sopenharmony_ci if (length >= 4 && context_p->source_p[3] == (uint8_t) LIT_CHAR_EQUALS) 1627425bb815Sopenharmony_ci { 1628425bb815Sopenharmony_ci context_p->token.type = LEXER_ASSIGN_UNS_RIGHT_SHIFT; 1629425bb815Sopenharmony_ci length = 4; 1630425bb815Sopenharmony_ci break; 1631425bb815Sopenharmony_ci } 1632425bb815Sopenharmony_ci 1633425bb815Sopenharmony_ci context_p->token.type = LEXER_UNS_RIGHT_SHIFT; 1634425bb815Sopenharmony_ci length = 3; 1635425bb815Sopenharmony_ci break; 1636425bb815Sopenharmony_ci } 1637425bb815Sopenharmony_ci } 1638425bb815Sopenharmony_ci 1639425bb815Sopenharmony_ci context_p->token.type = LEXER_RIGHT_SHIFT; 1640425bb815Sopenharmony_ci length = 2; 1641425bb815Sopenharmony_ci break; 1642425bb815Sopenharmony_ci } 1643425bb815Sopenharmony_ci } 1644425bb815Sopenharmony_ci 1645425bb815Sopenharmony_ci context_p->token.type = LEXER_GREATER; 1646425bb815Sopenharmony_ci length = 1; 1647425bb815Sopenharmony_ci break; 1648425bb815Sopenharmony_ci } 1649425bb815Sopenharmony_ci 1650425bb815Sopenharmony_ci case (uint8_t) LIT_CHAR_EQUALS: 1651425bb815Sopenharmony_ci { 1652425bb815Sopenharmony_ci if (length >= 2) 1653425bb815Sopenharmony_ci { 1654425bb815Sopenharmony_ci if (context_p->source_p[1] == (uint8_t) LIT_CHAR_EQUALS) 1655425bb815Sopenharmony_ci { 1656425bb815Sopenharmony_ci if (length >= 3 && context_p->source_p[2] == (uint8_t) LIT_CHAR_EQUALS) 1657425bb815Sopenharmony_ci { 1658425bb815Sopenharmony_ci context_p->token.type = LEXER_STRICT_EQUAL; 1659425bb815Sopenharmony_ci length = 3; 1660425bb815Sopenharmony_ci break; 1661425bb815Sopenharmony_ci } 1662425bb815Sopenharmony_ci 1663425bb815Sopenharmony_ci context_p->token.type = LEXER_EQUAL; 1664425bb815Sopenharmony_ci length = 2; 1665425bb815Sopenharmony_ci break; 1666425bb815Sopenharmony_ci } 1667425bb815Sopenharmony_ci 1668425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1669425bb815Sopenharmony_ci if (context_p->source_p[1] == (uint8_t) LIT_CHAR_GREATER_THAN) 1670425bb815Sopenharmony_ci { 1671425bb815Sopenharmony_ci context_p->token.type = LEXER_ARROW; 1672425bb815Sopenharmony_ci length = 2; 1673425bb815Sopenharmony_ci break; 1674425bb815Sopenharmony_ci } 1675425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1676425bb815Sopenharmony_ci } 1677425bb815Sopenharmony_ci 1678425bb815Sopenharmony_ci context_p->token.type = LEXER_ASSIGN; 1679425bb815Sopenharmony_ci length = 1; 1680425bb815Sopenharmony_ci break; 1681425bb815Sopenharmony_ci } 1682425bb815Sopenharmony_ci 1683425bb815Sopenharmony_ci case (uint8_t) LIT_CHAR_EXCLAMATION: 1684425bb815Sopenharmony_ci { 1685425bb815Sopenharmony_ci if (length >= 2 && context_p->source_p[1] == (uint8_t) LIT_CHAR_EQUALS) 1686425bb815Sopenharmony_ci { 1687425bb815Sopenharmony_ci if (length >= 3 && context_p->source_p[2] == (uint8_t) LIT_CHAR_EQUALS) 1688425bb815Sopenharmony_ci { 1689425bb815Sopenharmony_ci context_p->token.type = LEXER_STRICT_NOT_EQUAL; 1690425bb815Sopenharmony_ci length = 3; 1691425bb815Sopenharmony_ci break; 1692425bb815Sopenharmony_ci } 1693425bb815Sopenharmony_ci 1694425bb815Sopenharmony_ci context_p->token.type = LEXER_NOT_EQUAL; 1695425bb815Sopenharmony_ci length = 2; 1696425bb815Sopenharmony_ci break; 1697425bb815Sopenharmony_ci } 1698425bb815Sopenharmony_ci 1699425bb815Sopenharmony_ci context_p->token.type = LEXER_LOGICAL_NOT; 1700425bb815Sopenharmony_ci length = 1; 1701425bb815Sopenharmony_ci break; 1702425bb815Sopenharmony_ci } 1703425bb815Sopenharmony_ci 1704425bb815Sopenharmony_ci LEXER_TYPE_C_TOKEN (LIT_CHAR_PLUS, LEXER_ADD, LIT_CHAR_EQUALS, 1705425bb815Sopenharmony_ci LEXER_ASSIGN_ADD, LIT_CHAR_PLUS, LEXER_INCREASE) 1706425bb815Sopenharmony_ci LEXER_TYPE_C_TOKEN (LIT_CHAR_MINUS, LEXER_SUBTRACT, LIT_CHAR_EQUALS, 1707425bb815Sopenharmony_ci LEXER_ASSIGN_SUBTRACT, LIT_CHAR_MINUS, LEXER_DECREASE) 1708425bb815Sopenharmony_ci 1709425bb815Sopenharmony_ci case (uint8_t) LIT_CHAR_ASTERISK: 1710425bb815Sopenharmony_ci { 1711425bb815Sopenharmony_ci if (length >= 2) 1712425bb815Sopenharmony_ci { 1713425bb815Sopenharmony_ci if (context_p->source_p[1] == (uint8_t) LIT_CHAR_EQUALS) 1714425bb815Sopenharmony_ci { 1715425bb815Sopenharmony_ci context_p->token.type = LEXER_ASSIGN_MULTIPLY; 1716425bb815Sopenharmony_ci length = 2; 1717425bb815Sopenharmony_ci break; 1718425bb815Sopenharmony_ci } 1719425bb815Sopenharmony_ci 1720425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1721425bb815Sopenharmony_ci if (context_p->source_p[1] == (uint8_t) LIT_CHAR_ASTERISK) 1722425bb815Sopenharmony_ci { 1723425bb815Sopenharmony_ci if (length >= 3 && context_p->source_p[2] == (uint8_t) LIT_CHAR_EQUALS) 1724425bb815Sopenharmony_ci { 1725425bb815Sopenharmony_ci context_p->token.type = LEXER_ASSIGN_EXPONENTIATION; 1726425bb815Sopenharmony_ci length = 3; 1727425bb815Sopenharmony_ci break; 1728425bb815Sopenharmony_ci } 1729425bb815Sopenharmony_ci 1730425bb815Sopenharmony_ci context_p->token.type = LEXER_EXPONENTIATION; 1731425bb815Sopenharmony_ci length = 2; 1732425bb815Sopenharmony_ci break; 1733425bb815Sopenharmony_ci } 1734425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1735425bb815Sopenharmony_ci } 1736425bb815Sopenharmony_ci 1737425bb815Sopenharmony_ci context_p->token.type = LEXER_MULTIPLY; 1738425bb815Sopenharmony_ci length = 1; 1739425bb815Sopenharmony_ci break; 1740425bb815Sopenharmony_ci } 1741425bb815Sopenharmony_ci 1742425bb815Sopenharmony_ci LEXER_TYPE_B_TOKEN (LIT_CHAR_SLASH, LEXER_DIVIDE, LIT_CHAR_EQUALS, 1743425bb815Sopenharmony_ci LEXER_ASSIGN_DIVIDE) 1744425bb815Sopenharmony_ci LEXER_TYPE_B_TOKEN (LIT_CHAR_PERCENT, LEXER_MODULO, LIT_CHAR_EQUALS, 1745425bb815Sopenharmony_ci LEXER_ASSIGN_MODULO) 1746425bb815Sopenharmony_ci 1747425bb815Sopenharmony_ci LEXER_TYPE_C_TOKEN (LIT_CHAR_AMPERSAND, LEXER_BIT_AND, LIT_CHAR_EQUALS, 1748425bb815Sopenharmony_ci LEXER_ASSIGN_BIT_AND, LIT_CHAR_AMPERSAND, LEXER_LOGICAL_AND) 1749425bb815Sopenharmony_ci LEXER_TYPE_C_TOKEN (LIT_CHAR_VLINE, LEXER_BIT_OR, LIT_CHAR_EQUALS, 1750425bb815Sopenharmony_ci LEXER_ASSIGN_BIT_OR, LIT_CHAR_VLINE, LEXER_LOGICAL_OR) 1751425bb815Sopenharmony_ci 1752425bb815Sopenharmony_ci LEXER_TYPE_B_TOKEN (LIT_CHAR_CIRCUMFLEX, LEXER_BIT_XOR, LIT_CHAR_EQUALS, 1753425bb815Sopenharmony_ci LEXER_ASSIGN_BIT_XOR) 1754425bb815Sopenharmony_ci 1755425bb815Sopenharmony_ci LEXER_TYPE_A_TOKEN (LIT_CHAR_TILDE, LEXER_BIT_NOT); 1756425bb815Sopenharmony_ci LEXER_TYPE_A_TOKEN (LIT_CHAR_QUESTION, LEXER_QUESTION_MARK); 1757425bb815Sopenharmony_ci LEXER_TYPE_A_TOKEN (LIT_CHAR_COLON, LEXER_COLON); 1758425bb815Sopenharmony_ci 1759425bb815Sopenharmony_ci case LIT_CHAR_SINGLE_QUOTE: 1760425bb815Sopenharmony_ci case LIT_CHAR_DOUBLE_QUOTE: 1761425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1762425bb815Sopenharmony_ci case LIT_CHAR_GRAVE_ACCENT: 1763425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1764425bb815Sopenharmony_ci { 1765425bb815Sopenharmony_ci lexer_parse_string (context_p, LEXER_STRING_NO_OPTS); 1766425bb815Sopenharmony_ci return; 1767425bb815Sopenharmony_ci } 1768425bb815Sopenharmony_ci 1769425bb815Sopenharmony_ci default: 1770425bb815Sopenharmony_ci { 1771425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_CHARACTER); 1772425bb815Sopenharmony_ci } 1773425bb815Sopenharmony_ci } 1774425bb815Sopenharmony_ci 1775425bb815Sopenharmony_ci context_p->source_p += length; 1776425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_LC (context_p->column, length); 1777425bb815Sopenharmony_ci} /* lexer_next_token */ 1778425bb815Sopenharmony_ci 1779425bb815Sopenharmony_ci#undef LEXER_TYPE_A_TOKEN 1780425bb815Sopenharmony_ci#undef LEXER_TYPE_B_TOKEN 1781425bb815Sopenharmony_ci#undef LEXER_TYPE_C_TOKEN 1782425bb815Sopenharmony_ci#undef LEXER_TYPE_D_TOKEN 1783425bb815Sopenharmony_ci 1784425bb815Sopenharmony_ci/** 1785425bb815Sopenharmony_ci * Checks whether the next token starts with the specified character. 1786425bb815Sopenharmony_ci * 1787425bb815Sopenharmony_ci * @return true - if the next is the specified character 1788425bb815Sopenharmony_ci * false - otherwise 1789425bb815Sopenharmony_ci */ 1790425bb815Sopenharmony_cibool 1791425bb815Sopenharmony_cilexer_check_next_character (parser_context_t *context_p, /**< context */ 1792425bb815Sopenharmony_ci lit_utf8_byte_t character) /**< specified character */ 1793425bb815Sopenharmony_ci{ 1794425bb815Sopenharmony_ci if (!(context_p->token.flags & LEXER_NO_SKIP_SPACES)) 1795425bb815Sopenharmony_ci { 1796425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 1797425bb815Sopenharmony_ci context_p->token.flags = (uint8_t) (context_p->token.flags | LEXER_NO_SKIP_SPACES); 1798425bb815Sopenharmony_ci } 1799425bb815Sopenharmony_ci 1800425bb815Sopenharmony_ci return (context_p->source_p < context_p->source_end_p 1801425bb815Sopenharmony_ci && context_p->source_p[0] == (uint8_t) character); 1802425bb815Sopenharmony_ci} /* lexer_check_next_character */ 1803425bb815Sopenharmony_ci 1804425bb815Sopenharmony_ci/** 1805425bb815Sopenharmony_ci * Checks whether the next token starts with either specified characters. 1806425bb815Sopenharmony_ci * 1807425bb815Sopenharmony_ci * @return true - if the next is the specified character 1808425bb815Sopenharmony_ci * false - otherwise 1809425bb815Sopenharmony_ci */ 1810425bb815Sopenharmony_cibool 1811425bb815Sopenharmony_cilexer_check_next_characters (parser_context_t *context_p, /**< context */ 1812425bb815Sopenharmony_ci lit_utf8_byte_t character1, /**< first alternative character */ 1813425bb815Sopenharmony_ci lit_utf8_byte_t character2) /**< second alternative character */ 1814425bb815Sopenharmony_ci{ 1815425bb815Sopenharmony_ci if (!(context_p->token.flags & LEXER_NO_SKIP_SPACES)) 1816425bb815Sopenharmony_ci { 1817425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 1818425bb815Sopenharmony_ci context_p->token.flags = (uint8_t) (context_p->token.flags | LEXER_NO_SKIP_SPACES); 1819425bb815Sopenharmony_ci } 1820425bb815Sopenharmony_ci 1821425bb815Sopenharmony_ci return (context_p->source_p < context_p->source_end_p 1822425bb815Sopenharmony_ci && (context_p->source_p[0] == (uint8_t) character1 1823425bb815Sopenharmony_ci || context_p->source_p[0] == (uint8_t) character2)); 1824425bb815Sopenharmony_ci} /* lexer_check_next_characters */ 1825425bb815Sopenharmony_ci 1826425bb815Sopenharmony_ci/** 1827425bb815Sopenharmony_ci * Consumes the next character. The character cannot be a white space. 1828425bb815Sopenharmony_ci * 1829425bb815Sopenharmony_ci * @return consumed character 1830425bb815Sopenharmony_ci */ 1831425bb815Sopenharmony_ciinline uint8_t JERRY_ATTR_ALWAYS_INLINE 1832425bb815Sopenharmony_cilexer_consume_next_character (parser_context_t *context_p) /**< context */ 1833425bb815Sopenharmony_ci{ 1834425bb815Sopenharmony_ci JERRY_ASSERT (context_p->source_p < context_p->source_end_p); 1835425bb815Sopenharmony_ci 1836425bb815Sopenharmony_ci context_p->token.flags &= (uint8_t) ~LEXER_NO_SKIP_SPACES; 1837425bb815Sopenharmony_ci 1838425bb815Sopenharmony_ci PARSER_PLUS_EQUAL_LC (context_p->column, 1); 1839425bb815Sopenharmony_ci return *context_p->source_p++; 1840425bb815Sopenharmony_ci} /* lexer_consume_next_character */ 1841425bb815Sopenharmony_ci 1842425bb815Sopenharmony_ci/** 1843425bb815Sopenharmony_ci * Checks whether the next character can be the start of a post primary expression 1844425bb815Sopenharmony_ci * 1845425bb815Sopenharmony_ci * Note: 1846425bb815Sopenharmony_ci * the result is not precise, but this inprecise result 1847425bb815Sopenharmony_ci * has no side effects for negating number literals 1848425bb815Sopenharmony_ci * 1849425bb815Sopenharmony_ci * @return true if the next character can be the start of a post primary expression 1850425bb815Sopenharmony_ci */ 1851425bb815Sopenharmony_cibool 1852425bb815Sopenharmony_cilexer_check_post_primary_exp (parser_context_t *context_p) /**< context */ 1853425bb815Sopenharmony_ci{ 1854425bb815Sopenharmony_ci if (!(context_p->token.flags & LEXER_NO_SKIP_SPACES)) 1855425bb815Sopenharmony_ci { 1856425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 1857425bb815Sopenharmony_ci context_p->token.flags = (uint8_t) (context_p->token.flags | LEXER_NO_SKIP_SPACES); 1858425bb815Sopenharmony_ci } 1859425bb815Sopenharmony_ci 1860425bb815Sopenharmony_ci if (context_p->source_p >= context_p->source_end_p) 1861425bb815Sopenharmony_ci { 1862425bb815Sopenharmony_ci return false; 1863425bb815Sopenharmony_ci } 1864425bb815Sopenharmony_ci 1865425bb815Sopenharmony_ci switch (context_p->source_p[0]) 1866425bb815Sopenharmony_ci { 1867425bb815Sopenharmony_ci case LIT_CHAR_DOT: 1868425bb815Sopenharmony_ci case LIT_CHAR_LEFT_PAREN: 1869425bb815Sopenharmony_ci case LIT_CHAR_LEFT_SQUARE: 1870425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1871425bb815Sopenharmony_ci case LIT_CHAR_GRAVE_ACCENT: 1872425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1873425bb815Sopenharmony_ci { 1874425bb815Sopenharmony_ci return true; 1875425bb815Sopenharmony_ci } 1876425bb815Sopenharmony_ci case LIT_CHAR_PLUS: 1877425bb815Sopenharmony_ci case LIT_CHAR_MINUS: 1878425bb815Sopenharmony_ci { 1879425bb815Sopenharmony_ci return (!(context_p->token.flags & LEXER_WAS_NEWLINE) 1880425bb815Sopenharmony_ci && context_p->source_p + 1 < context_p->source_end_p 1881425bb815Sopenharmony_ci && context_p->source_p[1] == context_p->source_p[0]); 1882425bb815Sopenharmony_ci } 1883425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1884425bb815Sopenharmony_ci case LIT_CHAR_ASTERISK: 1885425bb815Sopenharmony_ci { 1886425bb815Sopenharmony_ci return (context_p->source_p + 1 < context_p->source_end_p 1887425bb815Sopenharmony_ci && context_p->source_p[1] == (uint8_t) LIT_CHAR_ASTERISK); 1888425bb815Sopenharmony_ci } 1889425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1890425bb815Sopenharmony_ci } 1891425bb815Sopenharmony_ci 1892425bb815Sopenharmony_ci return false; 1893425bb815Sopenharmony_ci} /* lexer_check_post_primary_exp */ 1894425bb815Sopenharmony_ci 1895425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1896425bb815Sopenharmony_ci 1897425bb815Sopenharmony_ci/** 1898425bb815Sopenharmony_ci * Checks whether the next token is a type used for detecting arrow functions. 1899425bb815Sopenharmony_ci * 1900425bb815Sopenharmony_ci * @return true if the next token is an arrow token 1901425bb815Sopenharmony_ci */ 1902425bb815Sopenharmony_cibool 1903425bb815Sopenharmony_cilexer_check_arrow (parser_context_t *context_p) /**< context */ 1904425bb815Sopenharmony_ci{ 1905425bb815Sopenharmony_ci if (!(context_p->token.flags & LEXER_NO_SKIP_SPACES)) 1906425bb815Sopenharmony_ci { 1907425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 1908425bb815Sopenharmony_ci context_p->token.flags = (uint8_t) (context_p->token.flags | LEXER_NO_SKIP_SPACES); 1909425bb815Sopenharmony_ci } 1910425bb815Sopenharmony_ci 1911425bb815Sopenharmony_ci return (!(context_p->token.flags & LEXER_WAS_NEWLINE) 1912425bb815Sopenharmony_ci && context_p->source_p + 2 <= context_p->source_end_p 1913425bb815Sopenharmony_ci && context_p->source_p[0] == (uint8_t) LIT_CHAR_EQUALS 1914425bb815Sopenharmony_ci && context_p->source_p[1] == (uint8_t) LIT_CHAR_GREATER_THAN); 1915425bb815Sopenharmony_ci} /* lexer_check_arrow */ 1916425bb815Sopenharmony_ci 1917425bb815Sopenharmony_ci/** 1918425bb815Sopenharmony_ci * Checks whether the next token is a comma or equal sign. 1919425bb815Sopenharmony_ci * 1920425bb815Sopenharmony_ci * @return true if the next token is a comma or equal sign 1921425bb815Sopenharmony_ci */ 1922425bb815Sopenharmony_cibool 1923425bb815Sopenharmony_cilexer_check_arrow_param (parser_context_t *context_p) /**< context */ 1924425bb815Sopenharmony_ci{ 1925425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.flags & LEXER_NO_SKIP_SPACES); 1926425bb815Sopenharmony_ci 1927425bb815Sopenharmony_ci if (context_p->source_p >= context_p->source_end_p) 1928425bb815Sopenharmony_ci { 1929425bb815Sopenharmony_ci return false; 1930425bb815Sopenharmony_ci } 1931425bb815Sopenharmony_ci 1932425bb815Sopenharmony_ci if (context_p->source_p[0] == LIT_CHAR_COMMA) 1933425bb815Sopenharmony_ci { 1934425bb815Sopenharmony_ci return true; 1935425bb815Sopenharmony_ci } 1936425bb815Sopenharmony_ci 1937425bb815Sopenharmony_ci if (context_p->source_p[0] != LIT_CHAR_EQUALS) 1938425bb815Sopenharmony_ci { 1939425bb815Sopenharmony_ci return false; 1940425bb815Sopenharmony_ci } 1941425bb815Sopenharmony_ci 1942425bb815Sopenharmony_ci return (context_p->source_p + 1 >= context_p->source_end_p 1943425bb815Sopenharmony_ci || context_p->source_p[1] != LIT_CHAR_EQUALS); 1944425bb815Sopenharmony_ci} /* lexer_check_arrow_param */ 1945425bb815Sopenharmony_ci 1946425bb815Sopenharmony_ci/** 1947425bb815Sopenharmony_ci * Checks whether the yield expression has no argument. 1948425bb815Sopenharmony_ci * 1949425bb815Sopenharmony_ci * @return true if it has no argument 1950425bb815Sopenharmony_ci */ 1951425bb815Sopenharmony_cibool 1952425bb815Sopenharmony_cilexer_check_yield_no_arg (parser_context_t *context_p) /**< context */ 1953425bb815Sopenharmony_ci{ 1954425bb815Sopenharmony_ci if (context_p->token.flags & LEXER_WAS_NEWLINE) 1955425bb815Sopenharmony_ci { 1956425bb815Sopenharmony_ci return true; 1957425bb815Sopenharmony_ci } 1958425bb815Sopenharmony_ci 1959425bb815Sopenharmony_ci switch (context_p->token.type) 1960425bb815Sopenharmony_ci { 1961425bb815Sopenharmony_ci case LEXER_RIGHT_BRACE: 1962425bb815Sopenharmony_ci case LEXER_RIGHT_PAREN: 1963425bb815Sopenharmony_ci case LEXER_RIGHT_SQUARE: 1964425bb815Sopenharmony_ci case LEXER_COMMA: 1965425bb815Sopenharmony_ci case LEXER_COLON: 1966425bb815Sopenharmony_ci case LEXER_SEMICOLON: 1967425bb815Sopenharmony_ci case LEXER_EOS: 1968425bb815Sopenharmony_ci { 1969425bb815Sopenharmony_ci return true; 1970425bb815Sopenharmony_ci } 1971425bb815Sopenharmony_ci default: 1972425bb815Sopenharmony_ci { 1973425bb815Sopenharmony_ci return false; 1974425bb815Sopenharmony_ci } 1975425bb815Sopenharmony_ci } 1976425bb815Sopenharmony_ci} /* lexer_check_yield_no_arg */ 1977425bb815Sopenharmony_ci 1978425bb815Sopenharmony_ci/** 1979425bb815Sopenharmony_ci * Checks whether the next token is a multiply and consumes it. 1980425bb815Sopenharmony_ci * 1981425bb815Sopenharmony_ci * @return true if the next token is a multiply 1982425bb815Sopenharmony_ci */ 1983425bb815Sopenharmony_cibool 1984425bb815Sopenharmony_cilexer_consume_generator (parser_context_t *context_p) /**< context */ 1985425bb815Sopenharmony_ci{ 1986425bb815Sopenharmony_ci if (!(context_p->token.flags & LEXER_NO_SKIP_SPACES)) 1987425bb815Sopenharmony_ci { 1988425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 1989425bb815Sopenharmony_ci context_p->token.flags = (uint8_t) (context_p->token.flags | LEXER_NO_SKIP_SPACES); 1990425bb815Sopenharmony_ci } 1991425bb815Sopenharmony_ci 1992425bb815Sopenharmony_ci if (context_p->source_p >= context_p->source_end_p 1993425bb815Sopenharmony_ci || context_p->source_p[0] != LIT_CHAR_ASTERISK 1994425bb815Sopenharmony_ci || (context_p->source_p + 1 < context_p->source_end_p 1995425bb815Sopenharmony_ci && (context_p->source_p[1] == LIT_CHAR_EQUALS || context_p->source_p[1] == LIT_CHAR_ASTERISK))) 1996425bb815Sopenharmony_ci { 1997425bb815Sopenharmony_ci return false; 1998425bb815Sopenharmony_ci } 1999425bb815Sopenharmony_ci 2000425bb815Sopenharmony_ci lexer_consume_next_character (context_p); 2001425bb815Sopenharmony_ci context_p->token.type = LEXER_MULTIPLY; 2002425bb815Sopenharmony_ci return true; 2003425bb815Sopenharmony_ci} /* lexer_consume_generator */ 2004425bb815Sopenharmony_ci 2005425bb815Sopenharmony_ci/** 2006425bb815Sopenharmony_ci * Update await / yield keywords after an arrow function with expression. 2007425bb815Sopenharmony_ci */ 2008425bb815Sopenharmony_civoid 2009425bb815Sopenharmony_cilexer_update_await_yield (parser_context_t *context_p, /**< context */ 2010425bb815Sopenharmony_ci uint32_t status_flags) /**< parser status flags after restore */ 2011425bb815Sopenharmony_ci{ 2012425bb815Sopenharmony_ci if (!(status_flags & PARSER_IS_STRICT)) 2013425bb815Sopenharmony_ci { 2014425bb815Sopenharmony_ci if (status_flags & PARSER_IS_GENERATOR_FUNCTION) 2015425bb815Sopenharmony_ci { 2016425bb815Sopenharmony_ci if (context_p->token.type == LEXER_LITERAL 2017425bb815Sopenharmony_ci && context_p->token.keyword_type == LEXER_KEYW_YIELD) 2018425bb815Sopenharmony_ci { 2019425bb815Sopenharmony_ci context_p->token.type = LEXER_KEYW_YIELD; 2020425bb815Sopenharmony_ci } 2021425bb815Sopenharmony_ci } 2022425bb815Sopenharmony_ci else 2023425bb815Sopenharmony_ci { 2024425bb815Sopenharmony_ci if (context_p->token.type == LEXER_KEYW_YIELD) 2025425bb815Sopenharmony_ci { 2026425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.keyword_type == LEXER_KEYW_YIELD); 2027425bb815Sopenharmony_ci context_p->token.type = LEXER_LITERAL; 2028425bb815Sopenharmony_ci } 2029425bb815Sopenharmony_ci } 2030425bb815Sopenharmony_ci } 2031425bb815Sopenharmony_ci 2032425bb815Sopenharmony_ci if (!(context_p->global_status_flags & ECMA_PARSE_MODULE)) 2033425bb815Sopenharmony_ci { 2034425bb815Sopenharmony_ci if (status_flags & PARSER_IS_ASYNC_FUNCTION) 2035425bb815Sopenharmony_ci { 2036425bb815Sopenharmony_ci if (context_p->token.type == LEXER_LITERAL 2037425bb815Sopenharmony_ci && context_p->token.keyword_type == LEXER_KEYW_AWAIT) 2038425bb815Sopenharmony_ci { 2039425bb815Sopenharmony_ci context_p->token.type = LEXER_KEYW_AWAIT; 2040425bb815Sopenharmony_ci } 2041425bb815Sopenharmony_ci } 2042425bb815Sopenharmony_ci else 2043425bb815Sopenharmony_ci { 2044425bb815Sopenharmony_ci if (context_p->token.type == LEXER_KEYW_AWAIT) 2045425bb815Sopenharmony_ci { 2046425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.keyword_type == LEXER_KEYW_AWAIT); 2047425bb815Sopenharmony_ci context_p->token.type = LEXER_LITERAL; 2048425bb815Sopenharmony_ci } 2049425bb815Sopenharmony_ci } 2050425bb815Sopenharmony_ci } 2051425bb815Sopenharmony_ci} /* lexer_update_await_yield */ 2052425bb815Sopenharmony_ci 2053425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2054425bb815Sopenharmony_ci 2055425bb815Sopenharmony_ci/** 2056425bb815Sopenharmony_ci * Convert an ident with escapes to a utf8 string. 2057425bb815Sopenharmony_ci */ 2058425bb815Sopenharmony_civoid 2059425bb815Sopenharmony_cilexer_convert_ident_to_cesu8 (uint8_t *destination_p, /**< destination string */ 2060425bb815Sopenharmony_ci const uint8_t *source_p, /**< source string */ 2061425bb815Sopenharmony_ci prop_length_t length) /**< length of destination string */ 2062425bb815Sopenharmony_ci{ 2063425bb815Sopenharmony_ci const uint8_t *destination_end_p = destination_p + length; 2064425bb815Sopenharmony_ci 2065425bb815Sopenharmony_ci JERRY_ASSERT (length <= PARSER_MAXIMUM_IDENT_LENGTH); 2066425bb815Sopenharmony_ci 2067425bb815Sopenharmony_ci do 2068425bb815Sopenharmony_ci { 2069425bb815Sopenharmony_ci if (*source_p == LIT_CHAR_BACKSLASH) 2070425bb815Sopenharmony_ci { 2071425bb815Sopenharmony_ci source_p += 2; 2072425bb815Sopenharmony_ci destination_p += lit_code_point_to_cesu8_bytes (destination_p, 2073425bb815Sopenharmony_ci lexer_unchecked_hex_to_character (&source_p)); 2074425bb815Sopenharmony_ci continue; 2075425bb815Sopenharmony_ci } 2076425bb815Sopenharmony_ci 2077425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2078425bb815Sopenharmony_ci if (*source_p >= LIT_UTF8_4_BYTE_MARKER) 2079425bb815Sopenharmony_ci { 2080425bb815Sopenharmony_ci lit_four_byte_utf8_char_to_cesu8 (destination_p, source_p); 2081425bb815Sopenharmony_ci 2082425bb815Sopenharmony_ci destination_p += 6; 2083425bb815Sopenharmony_ci source_p += 4; 2084425bb815Sopenharmony_ci continue; 2085425bb815Sopenharmony_ci } 2086425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2087425bb815Sopenharmony_ci 2088425bb815Sopenharmony_ci *destination_p++ = *source_p++; 2089425bb815Sopenharmony_ci } 2090425bb815Sopenharmony_ci while (destination_p < destination_end_p); 2091425bb815Sopenharmony_ci} /* lexer_convert_ident_to_cesu8 */ 2092425bb815Sopenharmony_ci 2093425bb815Sopenharmony_ci/** 2094425bb815Sopenharmony_ci * Convert literal to character sequence 2095425bb815Sopenharmony_ci */ 2096425bb815Sopenharmony_ciconst uint8_t * 2097425bb815Sopenharmony_cilexer_convert_literal_to_chars (parser_context_t *context_p, /**< context */ 2098425bb815Sopenharmony_ci const lexer_lit_location_t *literal_p, /**< literal location */ 2099425bb815Sopenharmony_ci uint8_t *local_byte_array_p, /**< local byte array to store chars */ 2100425bb815Sopenharmony_ci lexer_string_options_t opts) /**< options */ 2101425bb815Sopenharmony_ci{ 2102425bb815Sopenharmony_ci JERRY_ASSERT (context_p->u.allocated_buffer_p == NULL); 2103425bb815Sopenharmony_ci 2104425bb815Sopenharmony_ci if (!literal_p->has_escape) 2105425bb815Sopenharmony_ci { 2106425bb815Sopenharmony_ci return literal_p->char_p; 2107425bb815Sopenharmony_ci } 2108425bb815Sopenharmony_ci 2109425bb815Sopenharmony_ci uint8_t *destination_start_p; 2110425bb815Sopenharmony_ci if (literal_p->length > LEXER_MAX_LITERAL_LOCAL_BUFFER_SIZE) 2111425bb815Sopenharmony_ci { 2112425bb815Sopenharmony_ci context_p->u.allocated_buffer_p = (uint8_t *) parser_malloc_local (context_p, literal_p->length); 2113425bb815Sopenharmony_ci context_p->allocated_buffer_size = literal_p->length; 2114425bb815Sopenharmony_ci destination_start_p = context_p->u.allocated_buffer_p; 2115425bb815Sopenharmony_ci } 2116425bb815Sopenharmony_ci else 2117425bb815Sopenharmony_ci { 2118425bb815Sopenharmony_ci destination_start_p = local_byte_array_p; 2119425bb815Sopenharmony_ci } 2120425bb815Sopenharmony_ci 2121425bb815Sopenharmony_ci if (literal_p->type == LEXER_IDENT_LITERAL) 2122425bb815Sopenharmony_ci { 2123425bb815Sopenharmony_ci lexer_convert_ident_to_cesu8 (destination_start_p, literal_p->char_p, literal_p->length); 2124425bb815Sopenharmony_ci return destination_start_p; 2125425bb815Sopenharmony_ci } 2126425bb815Sopenharmony_ci 2127425bb815Sopenharmony_ci const uint8_t *source_p = literal_p->char_p; 2128425bb815Sopenharmony_ci uint8_t *destination_p = destination_start_p; 2129425bb815Sopenharmony_ci 2130425bb815Sopenharmony_ci uint8_t str_end_character = source_p[-1]; 2131425bb815Sopenharmony_ci 2132425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2133425bb815Sopenharmony_ci if (str_end_character == LIT_CHAR_RIGHT_BRACE) 2134425bb815Sopenharmony_ci { 2135425bb815Sopenharmony_ci str_end_character = LIT_CHAR_GRAVE_ACCENT; 2136425bb815Sopenharmony_ci } 2137425bb815Sopenharmony_ci 2138425bb815Sopenharmony_ci bool is_raw = (opts & LEXER_STRING_RAW) != 0; 2139425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 2140425bb815Sopenharmony_ci JERRY_UNUSED (opts); 2141425bb815Sopenharmony_ci bool is_raw = false; 2142425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2143425bb815Sopenharmony_ci 2144425bb815Sopenharmony_ci while (true) 2145425bb815Sopenharmony_ci { 2146425bb815Sopenharmony_ci if (*source_p == str_end_character) 2147425bb815Sopenharmony_ci { 2148425bb815Sopenharmony_ci break; 2149425bb815Sopenharmony_ci } 2150425bb815Sopenharmony_ci 2151425bb815Sopenharmony_ci if (*source_p == LIT_CHAR_BACKSLASH && !is_raw) 2152425bb815Sopenharmony_ci { 2153425bb815Sopenharmony_ci uint8_t conv_character; 2154425bb815Sopenharmony_ci 2155425bb815Sopenharmony_ci source_p++; 2156425bb815Sopenharmony_ci JERRY_ASSERT (source_p < context_p->source_end_p); 2157425bb815Sopenharmony_ci 2158425bb815Sopenharmony_ci /* Newline is ignored. */ 2159425bb815Sopenharmony_ci if (*source_p == LIT_CHAR_CR) 2160425bb815Sopenharmony_ci { 2161425bb815Sopenharmony_ci source_p++; 2162425bb815Sopenharmony_ci JERRY_ASSERT (source_p < context_p->source_end_p); 2163425bb815Sopenharmony_ci 2164425bb815Sopenharmony_ci if (*source_p == LIT_CHAR_LF) 2165425bb815Sopenharmony_ci { 2166425bb815Sopenharmony_ci source_p++; 2167425bb815Sopenharmony_ci } 2168425bb815Sopenharmony_ci continue; 2169425bb815Sopenharmony_ci } 2170425bb815Sopenharmony_ci else if (*source_p == LIT_CHAR_LF) 2171425bb815Sopenharmony_ci { 2172425bb815Sopenharmony_ci source_p++; 2173425bb815Sopenharmony_ci continue; 2174425bb815Sopenharmony_ci } 2175425bb815Sopenharmony_ci else if (*source_p == LEXER_NEWLINE_LS_PS_BYTE_1 && LEXER_NEWLINE_LS_PS_BYTE_23 (source_p)) 2176425bb815Sopenharmony_ci { 2177425bb815Sopenharmony_ci source_p += 3; 2178425bb815Sopenharmony_ci continue; 2179425bb815Sopenharmony_ci } 2180425bb815Sopenharmony_ci 2181425bb815Sopenharmony_ci if (*source_p >= LIT_CHAR_0 && *source_p <= LIT_CHAR_3) 2182425bb815Sopenharmony_ci { 2183425bb815Sopenharmony_ci lit_code_point_t octal_number = (uint32_t) (*source_p - LIT_CHAR_0); 2184425bb815Sopenharmony_ci 2185425bb815Sopenharmony_ci source_p++; 2186425bb815Sopenharmony_ci JERRY_ASSERT (source_p < context_p->source_end_p); 2187425bb815Sopenharmony_ci 2188425bb815Sopenharmony_ci if (*source_p >= LIT_CHAR_0 && *source_p <= LIT_CHAR_7) 2189425bb815Sopenharmony_ci { 2190425bb815Sopenharmony_ci octal_number = octal_number * 8 + (uint32_t) (*source_p - LIT_CHAR_0); 2191425bb815Sopenharmony_ci source_p++; 2192425bb815Sopenharmony_ci JERRY_ASSERT (source_p < context_p->source_end_p); 2193425bb815Sopenharmony_ci 2194425bb815Sopenharmony_ci if (*source_p >= LIT_CHAR_0 && *source_p <= LIT_CHAR_7) 2195425bb815Sopenharmony_ci { 2196425bb815Sopenharmony_ci octal_number = octal_number * 8 + (uint32_t) (*source_p - LIT_CHAR_0); 2197425bb815Sopenharmony_ci source_p++; 2198425bb815Sopenharmony_ci JERRY_ASSERT (source_p < context_p->source_end_p); 2199425bb815Sopenharmony_ci } 2200425bb815Sopenharmony_ci } 2201425bb815Sopenharmony_ci 2202425bb815Sopenharmony_ci destination_p += lit_code_point_to_cesu8_bytes (destination_p, octal_number); 2203425bb815Sopenharmony_ci continue; 2204425bb815Sopenharmony_ci } 2205425bb815Sopenharmony_ci 2206425bb815Sopenharmony_ci if (*source_p >= LIT_CHAR_4 && *source_p <= LIT_CHAR_7) 2207425bb815Sopenharmony_ci { 2208425bb815Sopenharmony_ci uint32_t octal_number = (uint32_t) (*source_p - LIT_CHAR_0); 2209425bb815Sopenharmony_ci 2210425bb815Sopenharmony_ci source_p++; 2211425bb815Sopenharmony_ci JERRY_ASSERT (source_p < context_p->source_end_p); 2212425bb815Sopenharmony_ci 2213425bb815Sopenharmony_ci if (*source_p >= LIT_CHAR_0 && *source_p <= LIT_CHAR_7) 2214425bb815Sopenharmony_ci { 2215425bb815Sopenharmony_ci octal_number = octal_number * 8 + (uint32_t) (*source_p - LIT_CHAR_0); 2216425bb815Sopenharmony_ci source_p++; 2217425bb815Sopenharmony_ci JERRY_ASSERT (source_p < context_p->source_end_p); 2218425bb815Sopenharmony_ci } 2219425bb815Sopenharmony_ci 2220425bb815Sopenharmony_ci *destination_p++ = (uint8_t) octal_number; 2221425bb815Sopenharmony_ci continue; 2222425bb815Sopenharmony_ci } 2223425bb815Sopenharmony_ci 2224425bb815Sopenharmony_ci if (*source_p == LIT_CHAR_LOWERCASE_X || *source_p == LIT_CHAR_LOWERCASE_U) 2225425bb815Sopenharmony_ci { 2226425bb815Sopenharmony_ci source_p++; 2227425bb815Sopenharmony_ci destination_p += lit_code_point_to_cesu8_bytes (destination_p, 2228425bb815Sopenharmony_ci lexer_unchecked_hex_to_character (&source_p)); 2229425bb815Sopenharmony_ci continue; 2230425bb815Sopenharmony_ci } 2231425bb815Sopenharmony_ci 2232425bb815Sopenharmony_ci conv_character = *source_p; 2233425bb815Sopenharmony_ci switch (*source_p) 2234425bb815Sopenharmony_ci { 2235425bb815Sopenharmony_ci case LIT_CHAR_LOWERCASE_B: 2236425bb815Sopenharmony_ci { 2237425bb815Sopenharmony_ci conv_character = 0x08; 2238425bb815Sopenharmony_ci break; 2239425bb815Sopenharmony_ci } 2240425bb815Sopenharmony_ci case LIT_CHAR_LOWERCASE_T: 2241425bb815Sopenharmony_ci { 2242425bb815Sopenharmony_ci conv_character = 0x09; 2243425bb815Sopenharmony_ci break; 2244425bb815Sopenharmony_ci } 2245425bb815Sopenharmony_ci case LIT_CHAR_LOWERCASE_N: 2246425bb815Sopenharmony_ci { 2247425bb815Sopenharmony_ci conv_character = 0x0a; 2248425bb815Sopenharmony_ci break; 2249425bb815Sopenharmony_ci } 2250425bb815Sopenharmony_ci case LIT_CHAR_LOWERCASE_V: 2251425bb815Sopenharmony_ci { 2252425bb815Sopenharmony_ci conv_character = 0x0b; 2253425bb815Sopenharmony_ci break; 2254425bb815Sopenharmony_ci } 2255425bb815Sopenharmony_ci case LIT_CHAR_LOWERCASE_F: 2256425bb815Sopenharmony_ci { 2257425bb815Sopenharmony_ci conv_character = 0x0c; 2258425bb815Sopenharmony_ci break; 2259425bb815Sopenharmony_ci } 2260425bb815Sopenharmony_ci case LIT_CHAR_LOWERCASE_R: 2261425bb815Sopenharmony_ci { 2262425bb815Sopenharmony_ci conv_character = 0x0d; 2263425bb815Sopenharmony_ci break; 2264425bb815Sopenharmony_ci } 2265425bb815Sopenharmony_ci } 2266425bb815Sopenharmony_ci 2267425bb815Sopenharmony_ci if (conv_character != *source_p) 2268425bb815Sopenharmony_ci { 2269425bb815Sopenharmony_ci *destination_p++ = conv_character; 2270425bb815Sopenharmony_ci source_p++; 2271425bb815Sopenharmony_ci continue; 2272425bb815Sopenharmony_ci } 2273425bb815Sopenharmony_ci } 2274425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2275425bb815Sopenharmony_ci else if (str_end_character == LIT_CHAR_GRAVE_ACCENT) 2276425bb815Sopenharmony_ci { 2277425bb815Sopenharmony_ci if (source_p[0] == LIT_CHAR_DOLLAR_SIGN 2278425bb815Sopenharmony_ci && source_p[1] == LIT_CHAR_LEFT_BRACE) 2279425bb815Sopenharmony_ci { 2280425bb815Sopenharmony_ci source_p++; 2281425bb815Sopenharmony_ci JERRY_ASSERT (source_p < context_p->source_end_p); 2282425bb815Sopenharmony_ci break; 2283425bb815Sopenharmony_ci } 2284425bb815Sopenharmony_ci if (*source_p == LIT_CHAR_CR) 2285425bb815Sopenharmony_ci { 2286425bb815Sopenharmony_ci *destination_p++ = LIT_CHAR_LF; 2287425bb815Sopenharmony_ci source_p++; 2288425bb815Sopenharmony_ci if (*source_p != str_end_character 2289425bb815Sopenharmony_ci && *source_p == LIT_CHAR_LF) 2290425bb815Sopenharmony_ci { 2291425bb815Sopenharmony_ci source_p++; 2292425bb815Sopenharmony_ci } 2293425bb815Sopenharmony_ci continue; 2294425bb815Sopenharmony_ci } 2295425bb815Sopenharmony_ci if ((*source_p == LIT_CHAR_BACKSLASH) && is_raw) 2296425bb815Sopenharmony_ci { 2297425bb815Sopenharmony_ci JERRY_ASSERT (source_p + 1 < context_p->source_end_p); 2298425bb815Sopenharmony_ci if ((*(source_p + 1) == LIT_CHAR_GRAVE_ACCENT) || (*(source_p + 1) == LIT_CHAR_BACKSLASH)) 2299425bb815Sopenharmony_ci { 2300425bb815Sopenharmony_ci *destination_p++ = *source_p++; 2301425bb815Sopenharmony_ci *destination_p++ = *source_p++; 2302425bb815Sopenharmony_ci continue; 2303425bb815Sopenharmony_ci } 2304425bb815Sopenharmony_ci } 2305425bb815Sopenharmony_ci } 2306425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2307425bb815Sopenharmony_ci 2308425bb815Sopenharmony_ci if (*source_p >= LIT_UTF8_4_BYTE_MARKER) 2309425bb815Sopenharmony_ci { 2310425bb815Sopenharmony_ci /* Processing 4 byte unicode sequence (even if it is 2311425bb815Sopenharmony_ci * after a backslash). Always converted to two 3 byte 2312425bb815Sopenharmony_ci * long sequence. */ 2313425bb815Sopenharmony_ci lit_four_byte_utf8_char_to_cesu8 (destination_p, source_p); 2314425bb815Sopenharmony_ci 2315425bb815Sopenharmony_ci destination_p += 6; 2316425bb815Sopenharmony_ci source_p += 4; 2317425bb815Sopenharmony_ci continue; 2318425bb815Sopenharmony_ci } 2319425bb815Sopenharmony_ci 2320425bb815Sopenharmony_ci *destination_p++ = *source_p++; 2321425bb815Sopenharmony_ci 2322425bb815Sopenharmony_ci /* There is no need to check the source_end_p 2323425bb815Sopenharmony_ci * since the string is terminated by a quotation mark. */ 2324425bb815Sopenharmony_ci while (IS_UTF8_INTERMEDIATE_OCTET (*source_p)) 2325425bb815Sopenharmony_ci { 2326425bb815Sopenharmony_ci *destination_p++ = *source_p++; 2327425bb815Sopenharmony_ci } 2328425bb815Sopenharmony_ci } 2329425bb815Sopenharmony_ci 2330425bb815Sopenharmony_ci JERRY_ASSERT (destination_p == destination_start_p + literal_p->length); 2331425bb815Sopenharmony_ci 2332425bb815Sopenharmony_ci return destination_start_p; 2333425bb815Sopenharmony_ci} /* lexer_convert_literal_to_chars */ 2334425bb815Sopenharmony_ci 2335425bb815Sopenharmony_ci/** 2336425bb815Sopenharmony_ci * Construct a literal object from an identifier. 2337425bb815Sopenharmony_ci */ 2338425bb815Sopenharmony_civoid 2339425bb815Sopenharmony_cilexer_construct_literal_object (parser_context_t *context_p, /**< context */ 2340425bb815Sopenharmony_ci const lexer_lit_location_t *lit_location_p, /**< literal location */ 2341425bb815Sopenharmony_ci uint8_t literal_type) /**< final literal type */ 2342425bb815Sopenharmony_ci{ 2343425bb815Sopenharmony_ci uint8_t local_byte_array[LEXER_MAX_LITERAL_LOCAL_BUFFER_SIZE]; 2344425bb815Sopenharmony_ci 2345425bb815Sopenharmony_ci const uint8_t *char_p = lexer_convert_literal_to_chars (context_p, 2346425bb815Sopenharmony_ci lit_location_p, 2347425bb815Sopenharmony_ci local_byte_array, 2348425bb815Sopenharmony_ci LEXER_STRING_NO_OPTS); 2349425bb815Sopenharmony_ci 2350425bb815Sopenharmony_ci size_t length = lit_location_p->length; 2351425bb815Sopenharmony_ci parser_list_iterator_t literal_iterator; 2352425bb815Sopenharmony_ci lexer_literal_t *literal_p; 2353425bb815Sopenharmony_ci uint32_t literal_index = 0; 2354425bb815Sopenharmony_ci bool search_scope_stack = (literal_type == LEXER_IDENT_LITERAL); 2355425bb815Sopenharmony_ci 2356425bb815Sopenharmony_ci if (JERRY_UNLIKELY (literal_type == LEXER_NEW_IDENT_LITERAL)) 2357425bb815Sopenharmony_ci { 2358425bb815Sopenharmony_ci literal_type = LEXER_IDENT_LITERAL; 2359425bb815Sopenharmony_ci } 2360425bb815Sopenharmony_ci 2361425bb815Sopenharmony_ci JERRY_ASSERT (literal_type == LEXER_IDENT_LITERAL 2362425bb815Sopenharmony_ci || literal_type == LEXER_STRING_LITERAL); 2363425bb815Sopenharmony_ci 2364425bb815Sopenharmony_ci JERRY_ASSERT (literal_type != LEXER_IDENT_LITERAL || length <= PARSER_MAXIMUM_IDENT_LENGTH); 2365425bb815Sopenharmony_ci JERRY_ASSERT (literal_type != LEXER_STRING_LITERAL || length <= PARSER_MAXIMUM_STRING_LENGTH); 2366425bb815Sopenharmony_ci 2367425bb815Sopenharmony_ci parser_list_iterator_init (&context_p->literal_pool, &literal_iterator); 2368425bb815Sopenharmony_ci 2369425bb815Sopenharmony_ci while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 2370425bb815Sopenharmony_ci { 2371425bb815Sopenharmony_ci if (literal_p->type == literal_type 2372425bb815Sopenharmony_ci && literal_p->prop.length == length 2373425bb815Sopenharmony_ci && memcmp (literal_p->u.char_p, char_p, length) == 0) 2374425bb815Sopenharmony_ci { 2375425bb815Sopenharmony_ci context_p->lit_object.literal_p = literal_p; 2376425bb815Sopenharmony_ci context_p->lit_object.index = (uint16_t) literal_index; 2377425bb815Sopenharmony_ci 2378425bb815Sopenharmony_ci parser_free_allocated_buffer (context_p); 2379425bb815Sopenharmony_ci 2380425bb815Sopenharmony_ci if (search_scope_stack) 2381425bb815Sopenharmony_ci { 2382425bb815Sopenharmony_ci parser_scope_stack_t *scope_stack_start_p = context_p->scope_stack_p; 2383425bb815Sopenharmony_ci parser_scope_stack_t *scope_stack_p = scope_stack_start_p + context_p->scope_stack_top; 2384425bb815Sopenharmony_ci 2385425bb815Sopenharmony_ci while (scope_stack_p > scope_stack_start_p) 2386425bb815Sopenharmony_ci { 2387425bb815Sopenharmony_ci scope_stack_p--; 2388425bb815Sopenharmony_ci 2389425bb815Sopenharmony_ci if (scope_stack_p->map_from == literal_index) 2390425bb815Sopenharmony_ci { 2391425bb815Sopenharmony_ci JERRY_ASSERT (scanner_decode_map_to (scope_stack_p) >= PARSER_REGISTER_START 2392425bb815Sopenharmony_ci || (literal_p->status_flags & LEXER_FLAG_USED)); 2393425bb815Sopenharmony_ci context_p->lit_object.index = scanner_decode_map_to (scope_stack_p); 2394425bb815Sopenharmony_ci return; 2395425bb815Sopenharmony_ci } 2396425bb815Sopenharmony_ci } 2397425bb815Sopenharmony_ci 2398425bb815Sopenharmony_ci literal_p->status_flags |= LEXER_FLAG_USED; 2399425bb815Sopenharmony_ci } 2400425bb815Sopenharmony_ci return; 2401425bb815Sopenharmony_ci } 2402425bb815Sopenharmony_ci 2403425bb815Sopenharmony_ci literal_index++; 2404425bb815Sopenharmony_ci } 2405425bb815Sopenharmony_ci 2406425bb815Sopenharmony_ci JERRY_ASSERT (literal_index == context_p->literal_count); 2407425bb815Sopenharmony_ci 2408425bb815Sopenharmony_ci if (literal_index >= PARSER_MAXIMUM_NUMBER_OF_LITERALS) 2409425bb815Sopenharmony_ci { 2410425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED); 2411425bb815Sopenharmony_ci } 2412425bb815Sopenharmony_ci 2413425bb815Sopenharmony_ci literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool); 2414425bb815Sopenharmony_ci literal_p->prop.length = (prop_length_t) length; 2415425bb815Sopenharmony_ci literal_p->type = literal_type; 2416425bb815Sopenharmony_ci 2417425bb815Sopenharmony_ci uint8_t status_flags = LEXER_FLAG_SOURCE_PTR; 2418425bb815Sopenharmony_ci 2419425bb815Sopenharmony_ci if (length > 0 && char_p == local_byte_array) 2420425bb815Sopenharmony_ci { 2421425bb815Sopenharmony_ci literal_p->u.char_p = (uint8_t *) jmem_heap_alloc_block (length); 2422425bb815Sopenharmony_ci memcpy ((uint8_t *) literal_p->u.char_p, char_p, length); 2423425bb815Sopenharmony_ci status_flags = 0; 2424425bb815Sopenharmony_ci } 2425425bb815Sopenharmony_ci else 2426425bb815Sopenharmony_ci { 2427425bb815Sopenharmony_ci literal_p->u.char_p = char_p; 2428425bb815Sopenharmony_ci 2429425bb815Sopenharmony_ci /* Buffer is taken over when a new literal is constructed. */ 2430425bb815Sopenharmony_ci if (context_p->u.allocated_buffer_p != NULL) 2431425bb815Sopenharmony_ci { 2432425bb815Sopenharmony_ci JERRY_ASSERT (char_p == context_p->u.allocated_buffer_p); 2433425bb815Sopenharmony_ci 2434425bb815Sopenharmony_ci context_p->u.allocated_buffer_p = NULL; 2435425bb815Sopenharmony_ci status_flags = 0; 2436425bb815Sopenharmony_ci } 2437425bb815Sopenharmony_ci } 2438425bb815Sopenharmony_ci 2439425bb815Sopenharmony_ci if (search_scope_stack) 2440425bb815Sopenharmony_ci { 2441425bb815Sopenharmony_ci status_flags |= LEXER_FLAG_USED; 2442425bb815Sopenharmony_ci } 2443425bb815Sopenharmony_ci 2444425bb815Sopenharmony_ci literal_p->status_flags = status_flags; 2445425bb815Sopenharmony_ci 2446425bb815Sopenharmony_ci context_p->lit_object.literal_p = literal_p; 2447425bb815Sopenharmony_ci context_p->lit_object.index = (uint16_t) literal_index; 2448425bb815Sopenharmony_ci context_p->literal_count++; 2449425bb815Sopenharmony_ci 2450425bb815Sopenharmony_ci JERRY_ASSERT (context_p->u.allocated_buffer_p == NULL); 2451425bb815Sopenharmony_ci} /* lexer_construct_literal_object */ 2452425bb815Sopenharmony_ci 2453425bb815Sopenharmony_ci/** 2454425bb815Sopenharmony_ci * Construct a number object. 2455425bb815Sopenharmony_ci * 2456425bb815Sopenharmony_ci * @return true if number is small number 2457425bb815Sopenharmony_ci */ 2458425bb815Sopenharmony_cibool 2459425bb815Sopenharmony_cilexer_construct_number_object (parser_context_t *context_p, /**< context */ 2460425bb815Sopenharmony_ci bool is_expr, /**< expression is parsed */ 2461425bb815Sopenharmony_ci bool is_negative_number) /**< sign is negative */ 2462425bb815Sopenharmony_ci{ 2463425bb815Sopenharmony_ci parser_list_iterator_t literal_iterator; 2464425bb815Sopenharmony_ci lexer_literal_t *literal_p; 2465425bb815Sopenharmony_ci ecma_number_t num; 2466425bb815Sopenharmony_ci uint32_t literal_index = 0; 2467425bb815Sopenharmony_ci prop_length_t length = context_p->token.lit_location.length; 2468425bb815Sopenharmony_ci 2469425bb815Sopenharmony_ci if (context_p->token.extra_value < LEXER_NUMBER_OCTAL) 2470425bb815Sopenharmony_ci { 2471425bb815Sopenharmony_ci num = ecma_utf8_string_to_number (context_p->token.lit_location.char_p, 2472425bb815Sopenharmony_ci length); 2473425bb815Sopenharmony_ci } 2474425bb815Sopenharmony_ci else 2475425bb815Sopenharmony_ci { 2476425bb815Sopenharmony_ci const uint8_t *src_p = context_p->token.lit_location.char_p; 2477425bb815Sopenharmony_ci const uint8_t *src_end_p = src_p + length - 1; 2478425bb815Sopenharmony_ci ecma_number_t multiplier = 8.0; 2479425bb815Sopenharmony_ci 2480425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2481425bb815Sopenharmony_ci if (context_p->token.extra_value == LEXER_NUMBER_BINARY) 2482425bb815Sopenharmony_ci { 2483425bb815Sopenharmony_ci multiplier = 2.0; 2484425bb815Sopenharmony_ci } 2485425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2486425bb815Sopenharmony_ci 2487425bb815Sopenharmony_ci num = 0; 2488425bb815Sopenharmony_ci do 2489425bb815Sopenharmony_ci { 2490425bb815Sopenharmony_ci src_p++; 2491425bb815Sopenharmony_ci num = num * multiplier + (ecma_number_t) (*src_p - LIT_CHAR_0); 2492425bb815Sopenharmony_ci } 2493425bb815Sopenharmony_ci while (src_p < src_end_p); 2494425bb815Sopenharmony_ci } 2495425bb815Sopenharmony_ci 2496425bb815Sopenharmony_ci if (is_expr) 2497425bb815Sopenharmony_ci { 2498425bb815Sopenharmony_ci int32_t int_num = (int32_t) num; 2499425bb815Sopenharmony_ci 2500425bb815Sopenharmony_ci if (int_num == num 2501425bb815Sopenharmony_ci && int_num <= CBC_PUSH_NUMBER_BYTE_RANGE_END 2502425bb815Sopenharmony_ci && (int_num != 0 || !is_negative_number)) 2503425bb815Sopenharmony_ci { 2504425bb815Sopenharmony_ci context_p->lit_object.index = (uint16_t) int_num; 2505425bb815Sopenharmony_ci return true; 2506425bb815Sopenharmony_ci } 2507425bb815Sopenharmony_ci } 2508425bb815Sopenharmony_ci 2509425bb815Sopenharmony_ci if (is_negative_number) 2510425bb815Sopenharmony_ci { 2511425bb815Sopenharmony_ci num = -num; 2512425bb815Sopenharmony_ci } 2513425bb815Sopenharmony_ci 2514425bb815Sopenharmony_ci ecma_value_t lit_value = ecma_find_or_create_literal_number (num); 2515425bb815Sopenharmony_ci parser_list_iterator_init (&context_p->literal_pool, &literal_iterator); 2516425bb815Sopenharmony_ci 2517425bb815Sopenharmony_ci while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 2518425bb815Sopenharmony_ci { 2519425bb815Sopenharmony_ci if (literal_p->type == LEXER_NUMBER_LITERAL 2520425bb815Sopenharmony_ci && literal_p->u.value == lit_value) 2521425bb815Sopenharmony_ci { 2522425bb815Sopenharmony_ci context_p->lit_object.literal_p = literal_p; 2523425bb815Sopenharmony_ci context_p->lit_object.index = (uint16_t) literal_index; 2524425bb815Sopenharmony_ci return false; 2525425bb815Sopenharmony_ci } 2526425bb815Sopenharmony_ci 2527425bb815Sopenharmony_ci literal_index++; 2528425bb815Sopenharmony_ci } 2529425bb815Sopenharmony_ci 2530425bb815Sopenharmony_ci JERRY_ASSERT (literal_index == context_p->literal_count); 2531425bb815Sopenharmony_ci 2532425bb815Sopenharmony_ci if (literal_index >= PARSER_MAXIMUM_NUMBER_OF_LITERALS) 2533425bb815Sopenharmony_ci { 2534425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED); 2535425bb815Sopenharmony_ci } 2536425bb815Sopenharmony_ci 2537425bb815Sopenharmony_ci literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool); 2538425bb815Sopenharmony_ci literal_p->u.value = lit_value; 2539425bb815Sopenharmony_ci literal_p->prop.length = 0; /* Unused. */ 2540425bb815Sopenharmony_ci literal_p->type = LEXER_NUMBER_LITERAL; 2541425bb815Sopenharmony_ci literal_p->status_flags = 0; 2542425bb815Sopenharmony_ci 2543425bb815Sopenharmony_ci context_p->lit_object.literal_p = literal_p; 2544425bb815Sopenharmony_ci context_p->lit_object.index = (uint16_t) literal_index; 2545425bb815Sopenharmony_ci 2546425bb815Sopenharmony_ci context_p->literal_count++; 2547425bb815Sopenharmony_ci return false; 2548425bb815Sopenharmony_ci} /* lexer_construct_number_object */ 2549425bb815Sopenharmony_ci 2550425bb815Sopenharmony_ci/** 2551425bb815Sopenharmony_ci * Convert a push number opcode to push literal opcode 2552425bb815Sopenharmony_ci */ 2553425bb815Sopenharmony_civoid 2554425bb815Sopenharmony_cilexer_convert_push_number_to_push_literal (parser_context_t *context_p) /**< context */ 2555425bb815Sopenharmony_ci{ 2556425bb815Sopenharmony_ci ecma_integer_value_t value; 2557425bb815Sopenharmony_ci bool two_literals = !PARSER_IS_BASIC_OPCODE (context_p->last_cbc_opcode); 2558425bb815Sopenharmony_ci 2559425bb815Sopenharmony_ci if (context_p->last_cbc_opcode == CBC_PUSH_NUMBER_0 2560425bb815Sopenharmony_ci || context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0)) 2561425bb815Sopenharmony_ci { 2562425bb815Sopenharmony_ci value = 0; 2563425bb815Sopenharmony_ci } 2564425bb815Sopenharmony_ci else if (context_p->last_cbc_opcode == CBC_PUSH_NUMBER_POS_BYTE 2565425bb815Sopenharmony_ci || context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)) 2566425bb815Sopenharmony_ci { 2567425bb815Sopenharmony_ci value = ((ecma_integer_value_t) context_p->last_cbc.value) + 1; 2568425bb815Sopenharmony_ci } 2569425bb815Sopenharmony_ci else 2570425bb815Sopenharmony_ci { 2571425bb815Sopenharmony_ci JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_NUMBER_NEG_BYTE 2572425bb815Sopenharmony_ci || context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)); 2573425bb815Sopenharmony_ci value = -((ecma_integer_value_t) context_p->last_cbc.value) - 1; 2574425bb815Sopenharmony_ci } 2575425bb815Sopenharmony_ci 2576425bb815Sopenharmony_ci ecma_value_t lit_value = ecma_make_integer_value (value); 2577425bb815Sopenharmony_ci 2578425bb815Sopenharmony_ci parser_list_iterator_t literal_iterator; 2579425bb815Sopenharmony_ci parser_list_iterator_init (&context_p->literal_pool, &literal_iterator); 2580425bb815Sopenharmony_ci 2581425bb815Sopenharmony_ci context_p->last_cbc_opcode = two_literals ? CBC_PUSH_TWO_LITERALS : CBC_PUSH_LITERAL; 2582425bb815Sopenharmony_ci 2583425bb815Sopenharmony_ci uint32_t literal_index = 0; 2584425bb815Sopenharmony_ci lexer_literal_t *literal_p; 2585425bb815Sopenharmony_ci 2586425bb815Sopenharmony_ci while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)) != NULL) 2587425bb815Sopenharmony_ci { 2588425bb815Sopenharmony_ci if (literal_p->type == LEXER_NUMBER_LITERAL 2589425bb815Sopenharmony_ci && literal_p->u.value == lit_value) 2590425bb815Sopenharmony_ci { 2591425bb815Sopenharmony_ci if (two_literals) 2592425bb815Sopenharmony_ci { 2593425bb815Sopenharmony_ci context_p->last_cbc.value = (uint16_t) literal_index; 2594425bb815Sopenharmony_ci } 2595425bb815Sopenharmony_ci else 2596425bb815Sopenharmony_ci { 2597425bb815Sopenharmony_ci context_p->last_cbc.literal_index = (uint16_t) literal_index; 2598425bb815Sopenharmony_ci } 2599425bb815Sopenharmony_ci return; 2600425bb815Sopenharmony_ci } 2601425bb815Sopenharmony_ci 2602425bb815Sopenharmony_ci literal_index++; 2603425bb815Sopenharmony_ci } 2604425bb815Sopenharmony_ci 2605425bb815Sopenharmony_ci JERRY_ASSERT (literal_index == context_p->literal_count); 2606425bb815Sopenharmony_ci 2607425bb815Sopenharmony_ci if (literal_index >= PARSER_MAXIMUM_NUMBER_OF_LITERALS) 2608425bb815Sopenharmony_ci { 2609425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED); 2610425bb815Sopenharmony_ci } 2611425bb815Sopenharmony_ci 2612425bb815Sopenharmony_ci literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool); 2613425bb815Sopenharmony_ci literal_p->u.value = lit_value; 2614425bb815Sopenharmony_ci literal_p->prop.length = 0; /* Unused. */ 2615425bb815Sopenharmony_ci literal_p->type = LEXER_NUMBER_LITERAL; 2616425bb815Sopenharmony_ci literal_p->status_flags = 0; 2617425bb815Sopenharmony_ci 2618425bb815Sopenharmony_ci context_p->literal_count++; 2619425bb815Sopenharmony_ci 2620425bb815Sopenharmony_ci if (two_literals) 2621425bb815Sopenharmony_ci { 2622425bb815Sopenharmony_ci context_p->last_cbc.value = (uint16_t) literal_index; 2623425bb815Sopenharmony_ci } 2624425bb815Sopenharmony_ci else 2625425bb815Sopenharmony_ci { 2626425bb815Sopenharmony_ci context_p->last_cbc.literal_index = (uint16_t) literal_index; 2627425bb815Sopenharmony_ci } 2628425bb815Sopenharmony_ci} /* lexer_convert_push_number_to_push_literal */ 2629425bb815Sopenharmony_ci 2630425bb815Sopenharmony_ci/** 2631425bb815Sopenharmony_ci * Construct a function literal object. 2632425bb815Sopenharmony_ci * 2633425bb815Sopenharmony_ci * @return function object literal index 2634425bb815Sopenharmony_ci */ 2635425bb815Sopenharmony_ciuint16_t 2636425bb815Sopenharmony_cilexer_construct_function_object (parser_context_t *context_p, /**< context */ 2637425bb815Sopenharmony_ci uint32_t extra_status_flags) /**< extra status flags */ 2638425bb815Sopenharmony_ci{ 2639425bb815Sopenharmony_ci ecma_compiled_code_t *compiled_code_p; 2640425bb815Sopenharmony_ci lexer_literal_t *literal_p; 2641425bb815Sopenharmony_ci uint16_t result_index; 2642425bb815Sopenharmony_ci 2643425bb815Sopenharmony_ci if (context_p->literal_count >= PARSER_MAXIMUM_NUMBER_OF_LITERALS) 2644425bb815Sopenharmony_ci { 2645425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED); 2646425bb815Sopenharmony_ci } 2647425bb815Sopenharmony_ci 2648425bb815Sopenharmony_ci parser_flush_cbc (context_p); 2649425bb815Sopenharmony_ci 2650425bb815Sopenharmony_ci if (context_p->status_flags & PARSER_INSIDE_WITH) 2651425bb815Sopenharmony_ci { 2652425bb815Sopenharmony_ci extra_status_flags |= PARSER_INSIDE_WITH; 2653425bb815Sopenharmony_ci } 2654425bb815Sopenharmony_ci 2655425bb815Sopenharmony_ci literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool); 2656425bb815Sopenharmony_ci literal_p->type = LEXER_UNUSED_LITERAL; 2657425bb815Sopenharmony_ci literal_p->status_flags = 0; 2658425bb815Sopenharmony_ci 2659425bb815Sopenharmony_ci result_index = context_p->literal_count; 2660425bb815Sopenharmony_ci context_p->literal_count++; 2661425bb815Sopenharmony_ci 2662425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2663425bb815Sopenharmony_ci if (!(extra_status_flags & PARSER_IS_ARROW_FUNCTION)) 2664425bb815Sopenharmony_ci { 2665425bb815Sopenharmony_ci compiled_code_p = parser_parse_function (context_p, extra_status_flags); 2666425bb815Sopenharmony_ci } 2667425bb815Sopenharmony_ci else 2668425bb815Sopenharmony_ci { 2669425bb815Sopenharmony_ci compiled_code_p = parser_parse_arrow_function (context_p, extra_status_flags); 2670425bb815Sopenharmony_ci } 2671425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 2672425bb815Sopenharmony_ci compiled_code_p = parser_parse_function (context_p, extra_status_flags); 2673425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2674425bb815Sopenharmony_ci 2675425bb815Sopenharmony_ci literal_p->u.bytecode_p = compiled_code_p; 2676425bb815Sopenharmony_ci literal_p->type = LEXER_FUNCTION_LITERAL; 2677425bb815Sopenharmony_ci 2678425bb815Sopenharmony_ci return result_index; 2679425bb815Sopenharmony_ci} /* lexer_construct_function_object */ 2680425bb815Sopenharmony_ci 2681425bb815Sopenharmony_ci/** 2682425bb815Sopenharmony_ci * Construct a regular expression object. 2683425bb815Sopenharmony_ci */ 2684425bb815Sopenharmony_civoid 2685425bb815Sopenharmony_cilexer_construct_regexp_object (parser_context_t *context_p, /**< context */ 2686425bb815Sopenharmony_ci bool parse_only) /**< parse only */ 2687425bb815Sopenharmony_ci{ 2688425bb815Sopenharmony_ci#if ENABLED (JERRY_BUILTIN_REGEXP) 2689425bb815Sopenharmony_ci const uint8_t *source_p = context_p->source_p; 2690425bb815Sopenharmony_ci const uint8_t *regex_start_p = context_p->source_p; 2691425bb815Sopenharmony_ci const uint8_t *regex_end_p = regex_start_p; 2692425bb815Sopenharmony_ci const uint8_t *source_end_p = context_p->source_end_p; 2693425bb815Sopenharmony_ci parser_line_counter_t column = context_p->column; 2694425bb815Sopenharmony_ci lexer_literal_t *literal_p; 2695425bb815Sopenharmony_ci bool in_class = false; 2696425bb815Sopenharmony_ci uint16_t current_flags; 2697425bb815Sopenharmony_ci lit_utf8_size_t length; 2698425bb815Sopenharmony_ci 2699425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_DIVIDE 2700425bb815Sopenharmony_ci || context_p->token.type == LEXER_ASSIGN_DIVIDE); 2701425bb815Sopenharmony_ci 2702425bb815Sopenharmony_ci if (context_p->token.type == LEXER_ASSIGN_DIVIDE) 2703425bb815Sopenharmony_ci { 2704425bb815Sopenharmony_ci regex_start_p--; 2705425bb815Sopenharmony_ci } 2706425bb815Sopenharmony_ci 2707425bb815Sopenharmony_ci while (true) 2708425bb815Sopenharmony_ci { 2709425bb815Sopenharmony_ci if (source_p >= source_end_p) 2710425bb815Sopenharmony_ci { 2711425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_UNTERMINATED_REGEXP); 2712425bb815Sopenharmony_ci } 2713425bb815Sopenharmony_ci 2714425bb815Sopenharmony_ci if (!in_class && source_p[0] == LIT_CHAR_SLASH) 2715425bb815Sopenharmony_ci { 2716425bb815Sopenharmony_ci regex_end_p = source_p; 2717425bb815Sopenharmony_ci source_p++; 2718425bb815Sopenharmony_ci column++; 2719425bb815Sopenharmony_ci break; 2720425bb815Sopenharmony_ci } 2721425bb815Sopenharmony_ci 2722425bb815Sopenharmony_ci switch (source_p[0]) 2723425bb815Sopenharmony_ci { 2724425bb815Sopenharmony_ci case LIT_CHAR_CR: 2725425bb815Sopenharmony_ci case LIT_CHAR_LF: 2726425bb815Sopenharmony_ci case LEXER_NEWLINE_LS_PS_BYTE_1: 2727425bb815Sopenharmony_ci { 2728425bb815Sopenharmony_ci if (source_p[0] != LEXER_NEWLINE_LS_PS_BYTE_1 2729425bb815Sopenharmony_ci || LEXER_NEWLINE_LS_PS_BYTE_23 (source_p)) 2730425bb815Sopenharmony_ci { 2731425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_NEWLINE_NOT_ALLOWED); 2732425bb815Sopenharmony_ci } 2733425bb815Sopenharmony_ci break; 2734425bb815Sopenharmony_ci } 2735425bb815Sopenharmony_ci case LIT_CHAR_TAB: 2736425bb815Sopenharmony_ci { 2737425bb815Sopenharmony_ci column = align_column_to_tab (column); 2738425bb815Sopenharmony_ci /* Subtract -1 because column is increased below. */ 2739425bb815Sopenharmony_ci column--; 2740425bb815Sopenharmony_ci break; 2741425bb815Sopenharmony_ci } 2742425bb815Sopenharmony_ci case LIT_CHAR_LEFT_SQUARE: 2743425bb815Sopenharmony_ci { 2744425bb815Sopenharmony_ci in_class = true; 2745425bb815Sopenharmony_ci break; 2746425bb815Sopenharmony_ci } 2747425bb815Sopenharmony_ci case LIT_CHAR_RIGHT_SQUARE: 2748425bb815Sopenharmony_ci { 2749425bb815Sopenharmony_ci in_class = false; 2750425bb815Sopenharmony_ci break; 2751425bb815Sopenharmony_ci } 2752425bb815Sopenharmony_ci case LIT_CHAR_BACKSLASH: 2753425bb815Sopenharmony_ci { 2754425bb815Sopenharmony_ci if (source_p + 1 >= source_end_p) 2755425bb815Sopenharmony_ci { 2756425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_UNTERMINATED_REGEXP); 2757425bb815Sopenharmony_ci } 2758425bb815Sopenharmony_ci 2759425bb815Sopenharmony_ci if (source_p[1] >= 0x20 && source_p[1] <= LIT_UTF8_1_BYTE_CODE_POINT_MAX) 2760425bb815Sopenharmony_ci { 2761425bb815Sopenharmony_ci source_p++; 2762425bb815Sopenharmony_ci column++; 2763425bb815Sopenharmony_ci } 2764425bb815Sopenharmony_ci } 2765425bb815Sopenharmony_ci } 2766425bb815Sopenharmony_ci 2767425bb815Sopenharmony_ci source_p++; 2768425bb815Sopenharmony_ci column++; 2769425bb815Sopenharmony_ci 2770425bb815Sopenharmony_ci while (source_p < source_end_p 2771425bb815Sopenharmony_ci && IS_UTF8_INTERMEDIATE_OCTET (source_p[0])) 2772425bb815Sopenharmony_ci { 2773425bb815Sopenharmony_ci source_p++; 2774425bb815Sopenharmony_ci } 2775425bb815Sopenharmony_ci } 2776425bb815Sopenharmony_ci 2777425bb815Sopenharmony_ci current_flags = 0; 2778425bb815Sopenharmony_ci while (source_p < source_end_p) 2779425bb815Sopenharmony_ci { 2780425bb815Sopenharmony_ci uint32_t flag = 0; 2781425bb815Sopenharmony_ci 2782425bb815Sopenharmony_ci if (source_p[0] == LIT_CHAR_LOWERCASE_G) 2783425bb815Sopenharmony_ci { 2784425bb815Sopenharmony_ci flag = RE_FLAG_GLOBAL; 2785425bb815Sopenharmony_ci } 2786425bb815Sopenharmony_ci else if (source_p[0] == LIT_CHAR_LOWERCASE_I) 2787425bb815Sopenharmony_ci { 2788425bb815Sopenharmony_ci flag = RE_FLAG_IGNORE_CASE; 2789425bb815Sopenharmony_ci } 2790425bb815Sopenharmony_ci else if (source_p[0] == LIT_CHAR_LOWERCASE_M) 2791425bb815Sopenharmony_ci { 2792425bb815Sopenharmony_ci flag = RE_FLAG_MULTILINE; 2793425bb815Sopenharmony_ci } 2794425bb815Sopenharmony_ci else if (source_p[0] == LIT_CHAR_LOWERCASE_U) 2795425bb815Sopenharmony_ci { 2796425bb815Sopenharmony_ci flag = RE_FLAG_UNICODE; 2797425bb815Sopenharmony_ci } 2798425bb815Sopenharmony_ci else if (source_p[0] == LIT_CHAR_LOWERCASE_Y) 2799425bb815Sopenharmony_ci { 2800425bb815Sopenharmony_ci flag = RE_FLAG_STICKY; 2801425bb815Sopenharmony_ci } 2802425bb815Sopenharmony_ci 2803425bb815Sopenharmony_ci if (flag == 0) 2804425bb815Sopenharmony_ci { 2805425bb815Sopenharmony_ci break; 2806425bb815Sopenharmony_ci } 2807425bb815Sopenharmony_ci 2808425bb815Sopenharmony_ci if (current_flags & flag) 2809425bb815Sopenharmony_ci { 2810425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_DUPLICATED_REGEXP_FLAG); 2811425bb815Sopenharmony_ci } 2812425bb815Sopenharmony_ci 2813425bb815Sopenharmony_ci current_flags = (uint16_t) (current_flags | flag); 2814425bb815Sopenharmony_ci source_p++; 2815425bb815Sopenharmony_ci column++; 2816425bb815Sopenharmony_ci } 2817425bb815Sopenharmony_ci 2818425bb815Sopenharmony_ci context_p->source_p = source_p; 2819425bb815Sopenharmony_ci context_p->column = column; 2820425bb815Sopenharmony_ci 2821425bb815Sopenharmony_ci if (source_p < source_end_p && lexer_parse_identifier (context_p, LEXER_PARSE_CHECK_PART_AND_RETURN)) 2822425bb815Sopenharmony_ci { 2823425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_UNKNOWN_REGEXP_FLAG); 2824425bb815Sopenharmony_ci } 2825425bb815Sopenharmony_ci 2826425bb815Sopenharmony_ci length = (lit_utf8_size_t) (regex_end_p - regex_start_p); 2827425bb815Sopenharmony_ci if (length > PARSER_MAXIMUM_STRING_LENGTH) 2828425bb815Sopenharmony_ci { 2829425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_REGEXP_TOO_LONG); 2830425bb815Sopenharmony_ci } 2831425bb815Sopenharmony_ci 2832425bb815Sopenharmony_ci context_p->column = column; 2833425bb815Sopenharmony_ci context_p->source_p = source_p; 2834425bb815Sopenharmony_ci 2835425bb815Sopenharmony_ci if (parse_only) 2836425bb815Sopenharmony_ci { 2837425bb815Sopenharmony_ci return; 2838425bb815Sopenharmony_ci } 2839425bb815Sopenharmony_ci 2840425bb815Sopenharmony_ci if (context_p->literal_count >= PARSER_MAXIMUM_NUMBER_OF_LITERALS) 2841425bb815Sopenharmony_ci { 2842425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED); 2843425bb815Sopenharmony_ci } 2844425bb815Sopenharmony_ci 2845425bb815Sopenharmony_ci literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool); 2846425bb815Sopenharmony_ci literal_p->prop.length = (prop_length_t) length; 2847425bb815Sopenharmony_ci literal_p->type = LEXER_UNUSED_LITERAL; 2848425bb815Sopenharmony_ci literal_p->status_flags = 0; 2849425bb815Sopenharmony_ci 2850425bb815Sopenharmony_ci context_p->literal_count++; 2851425bb815Sopenharmony_ci 2852425bb815Sopenharmony_ci /* Compile the RegExp literal and store the RegExp bytecode pointer */ 2853425bb815Sopenharmony_ci ecma_string_t *pattern_str_p = NULL; 2854425bb815Sopenharmony_ci 2855425bb815Sopenharmony_ci if (lit_is_valid_cesu8_string (regex_start_p, length)) 2856425bb815Sopenharmony_ci { 2857425bb815Sopenharmony_ci pattern_str_p = ecma_new_ecma_string_from_utf8 (regex_start_p, length); 2858425bb815Sopenharmony_ci } 2859425bb815Sopenharmony_ci else 2860425bb815Sopenharmony_ci { 2861425bb815Sopenharmony_ci JERRY_ASSERT (lit_is_valid_utf8_string (regex_start_p, length)); 2862425bb815Sopenharmony_ci pattern_str_p = ecma_new_ecma_string_from_utf8_converted_to_cesu8 (regex_start_p, length); 2863425bb815Sopenharmony_ci } 2864425bb815Sopenharmony_ci 2865425bb815Sopenharmony_ci re_compiled_code_t *re_bytecode_p = re_compile_bytecode (pattern_str_p, current_flags); 2866425bb815Sopenharmony_ci ecma_deref_ecma_string (pattern_str_p); 2867425bb815Sopenharmony_ci 2868425bb815Sopenharmony_ci if (JERRY_UNLIKELY (re_bytecode_p == NULL)) 2869425bb815Sopenharmony_ci { 2870425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_INVALID_REGEXP); 2871425bb815Sopenharmony_ci } 2872425bb815Sopenharmony_ci 2873425bb815Sopenharmony_ci literal_p->type = LEXER_REGEXP_LITERAL; 2874425bb815Sopenharmony_ci literal_p->u.bytecode_p = (ecma_compiled_code_t *) re_bytecode_p; 2875425bb815Sopenharmony_ci 2876425bb815Sopenharmony_ci context_p->token.type = LEXER_LITERAL; 2877425bb815Sopenharmony_ci context_p->token.keyword_type = LEXER_EOS; 2878425bb815Sopenharmony_ci context_p->token.lit_location.type = LEXER_REGEXP_LITERAL; 2879425bb815Sopenharmony_ci 2880425bb815Sopenharmony_ci context_p->lit_object.literal_p = literal_p; 2881425bb815Sopenharmony_ci context_p->lit_object.index = (uint16_t) (context_p->literal_count - 1); 2882425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_BUILTIN_REGEXP) */ 2883425bb815Sopenharmony_ci JERRY_UNUSED (parse_only); 2884425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_UNSUPPORTED_REGEXP); 2885425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */ 2886425bb815Sopenharmony_ci} /* lexer_construct_regexp_object */ 2887425bb815Sopenharmony_ci 2888425bb815Sopenharmony_ci/** 2889425bb815Sopenharmony_ci * Next token must be an identifier. 2890425bb815Sopenharmony_ci */ 2891425bb815Sopenharmony_civoid 2892425bb815Sopenharmony_cilexer_expect_identifier (parser_context_t *context_p, /**< context */ 2893425bb815Sopenharmony_ci uint8_t literal_type) /**< literal type */ 2894425bb815Sopenharmony_ci{ 2895425bb815Sopenharmony_ci JERRY_ASSERT (literal_type == LEXER_STRING_LITERAL 2896425bb815Sopenharmony_ci || literal_type == LEXER_IDENT_LITERAL 2897425bb815Sopenharmony_ci || literal_type == LEXER_NEW_IDENT_LITERAL); 2898425bb815Sopenharmony_ci 2899425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 2900425bb815Sopenharmony_ci context_p->token.line = context_p->line; 2901425bb815Sopenharmony_ci context_p->token.column = context_p->column; 2902425bb815Sopenharmony_ci 2903425bb815Sopenharmony_ci if (context_p->source_p < context_p->source_end_p 2904425bb815Sopenharmony_ci && lexer_parse_identifier (context_p, (literal_type != LEXER_STRING_LITERAL ? LEXER_PARSE_CHECK_KEYWORDS 2905425bb815Sopenharmony_ci : LEXER_PARSE_NO_OPTS))) 2906425bb815Sopenharmony_ci { 2907425bb815Sopenharmony_ci if (context_p->token.type == LEXER_LITERAL) 2908425bb815Sopenharmony_ci { 2909425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.lit_location.type == LEXER_IDENT_LITERAL); 2910425bb815Sopenharmony_ci 2911425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, 2912425bb815Sopenharmony_ci &context_p->token.lit_location, 2913425bb815Sopenharmony_ci literal_type); 2914425bb815Sopenharmony_ci 2915425bb815Sopenharmony_ci if (literal_type != LEXER_STRING_LITERAL 2916425bb815Sopenharmony_ci && (context_p->status_flags & PARSER_IS_STRICT)) 2917425bb815Sopenharmony_ci { 2918425bb815Sopenharmony_ci if (context_p->token.keyword_type == LEXER_KEYW_EVAL) 2919425bb815Sopenharmony_ci { 2920425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_EVAL_NOT_ALLOWED); 2921425bb815Sopenharmony_ci } 2922425bb815Sopenharmony_ci else if (context_p->token.keyword_type == LEXER_KEYW_ARGUMENTS) 2923425bb815Sopenharmony_ci { 2924425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_ARGUMENTS_NOT_ALLOWED); 2925425bb815Sopenharmony_ci } 2926425bb815Sopenharmony_ci } 2927425bb815Sopenharmony_ci return; 2928425bb815Sopenharmony_ci } 2929425bb815Sopenharmony_ci } 2930425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_MODULE_SYSTEM) 2931425bb815Sopenharmony_ci else if (context_p->status_flags & PARSER_MODULE_DEFAULT_CLASS_OR_FUNC) 2932425bb815Sopenharmony_ci { 2933425bb815Sopenharmony_ci /* When parsing default exports for modules, it is not required by functions or classes to have identifiers. 2934425bb815Sopenharmony_ci * In this case we use a synthetic name for them. */ 2935425bb815Sopenharmony_ci context_p->token.type = LEXER_LITERAL; 2936425bb815Sopenharmony_ci context_p->token.keyword_type = LEXER_EOS; 2937425bb815Sopenharmony_ci context_p->token.lit_location = lexer_default_literal; 2938425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, &context_p->token.lit_location, literal_type); 2939425bb815Sopenharmony_ci context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_DEFAULT_CLASS_OR_FUNC); 2940425bb815Sopenharmony_ci return; 2941425bb815Sopenharmony_ci } 2942425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */ 2943425bb815Sopenharmony_ci 2944425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2945425bb815Sopenharmony_ci if (context_p->token.type == LEXER_KEYW_YIELD) 2946425bb815Sopenharmony_ci { 2947425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_YIELD_NOT_ALLOWED); 2948425bb815Sopenharmony_ci } 2949425bb815Sopenharmony_ci if (context_p->token.type == LEXER_KEYW_AWAIT) 2950425bb815Sopenharmony_ci { 2951425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_AWAIT_NOT_ALLOWED); 2952425bb815Sopenharmony_ci } 2953425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2954425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED); 2955425bb815Sopenharmony_ci} /* lexer_expect_identifier */ 2956425bb815Sopenharmony_ci 2957425bb815Sopenharmony_ci/** 2958425bb815Sopenharmony_ci * Next token must be an identifier. 2959425bb815Sopenharmony_ci */ 2960425bb815Sopenharmony_civoid 2961425bb815Sopenharmony_cilexer_expect_object_literal_id (parser_context_t *context_p, /**< context */ 2962425bb815Sopenharmony_ci uint32_t ident_opts) /**< lexer_obj_ident_opts_t option bits */ 2963425bb815Sopenharmony_ci{ 2964425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 2965425bb815Sopenharmony_ci 2966425bb815Sopenharmony_ci if (context_p->source_p >= context_p->source_end_p) 2967425bb815Sopenharmony_ci { 2968425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_PROPERTY_IDENTIFIER_EXPECTED); 2969425bb815Sopenharmony_ci } 2970425bb815Sopenharmony_ci 2971425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2972425bb815Sopenharmony_ci int is_class_method = ((ident_opts & LEXER_OBJ_IDENT_CLASS_METHOD) 2973425bb815Sopenharmony_ci && !(ident_opts & LEXER_OBJ_IDENT_ONLY_IDENTIFIERS) 2974425bb815Sopenharmony_ci && (context_p->token.type != LEXER_KEYW_STATIC)); 2975425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2976425bb815Sopenharmony_ci 2977425bb815Sopenharmony_ci context_p->token.line = context_p->line; 2978425bb815Sopenharmony_ci context_p->token.column = context_p->column; 2979425bb815Sopenharmony_ci bool create_literal_object = false; 2980425bb815Sopenharmony_ci 2981425bb815Sopenharmony_ci if (lexer_parse_identifier (context_p, LEXER_PARSE_NO_OPTS)) 2982425bb815Sopenharmony_ci { 2983425bb815Sopenharmony_ci if (!(ident_opts & (LEXER_OBJ_IDENT_ONLY_IDENTIFIERS | LEXER_OBJ_IDENT_OBJECT_PATTERN))) 2984425bb815Sopenharmony_ci { 2985425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 2986425bb815Sopenharmony_ci context_p->token.flags = (uint8_t) (context_p->token.flags | LEXER_NO_SKIP_SPACES); 2987425bb815Sopenharmony_ci 2988425bb815Sopenharmony_ci if (context_p->source_p < context_p->source_end_p 2989425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2990425bb815Sopenharmony_ci && context_p->source_p[0] != LIT_CHAR_COMMA 2991425bb815Sopenharmony_ci && context_p->source_p[0] != LIT_CHAR_RIGHT_BRACE 2992425bb815Sopenharmony_ci && context_p->source_p[0] != LIT_CHAR_LEFT_PAREN 2993425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2994425bb815Sopenharmony_ci && context_p->source_p[0] != LIT_CHAR_COLON) 2995425bb815Sopenharmony_ci { 2996425bb815Sopenharmony_ci if (lexer_compare_literal_to_string (context_p, "get", 3)) 2997425bb815Sopenharmony_ci { 2998425bb815Sopenharmony_ci context_p->token.type = LEXER_PROPERTY_GETTER; 2999425bb815Sopenharmony_ci return; 3000425bb815Sopenharmony_ci } 3001425bb815Sopenharmony_ci 3002425bb815Sopenharmony_ci if (lexer_compare_literal_to_string (context_p, "set", 3)) 3003425bb815Sopenharmony_ci { 3004425bb815Sopenharmony_ci context_p->token.type = LEXER_PROPERTY_SETTER; 3005425bb815Sopenharmony_ci return; 3006425bb815Sopenharmony_ci } 3007425bb815Sopenharmony_ci 3008425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 3009425bb815Sopenharmony_ci if (lexer_compare_literal_to_string (context_p, "async", 5)) 3010425bb815Sopenharmony_ci { 3011425bb815Sopenharmony_ci context_p->token.type = LEXER_KEYW_ASYNC; 3012425bb815Sopenharmony_ci return; 3013425bb815Sopenharmony_ci } 3014425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 3015425bb815Sopenharmony_ci } 3016425bb815Sopenharmony_ci } 3017425bb815Sopenharmony_ci 3018425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 3019425bb815Sopenharmony_ci if (is_class_method && lexer_compare_literal_to_string (context_p, "static", 6)) 3020425bb815Sopenharmony_ci { 3021425bb815Sopenharmony_ci context_p->token.type = LEXER_KEYW_STATIC; 3022425bb815Sopenharmony_ci return; 3023425bb815Sopenharmony_ci } 3024425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 3025425bb815Sopenharmony_ci 3026425bb815Sopenharmony_ci create_literal_object = true; 3027425bb815Sopenharmony_ci } 3028425bb815Sopenharmony_ci else 3029425bb815Sopenharmony_ci { 3030425bb815Sopenharmony_ci switch (context_p->source_p[0]) 3031425bb815Sopenharmony_ci { 3032425bb815Sopenharmony_ci case LIT_CHAR_DOUBLE_QUOTE: 3033425bb815Sopenharmony_ci case LIT_CHAR_SINGLE_QUOTE: 3034425bb815Sopenharmony_ci { 3035425bb815Sopenharmony_ci lexer_parse_string (context_p, LEXER_STRING_NO_OPTS); 3036425bb815Sopenharmony_ci create_literal_object = true; 3037425bb815Sopenharmony_ci break; 3038425bb815Sopenharmony_ci } 3039425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 3040425bb815Sopenharmony_ci case LIT_CHAR_LEFT_SQUARE: 3041425bb815Sopenharmony_ci { 3042425bb815Sopenharmony_ci lexer_consume_next_character (context_p); 3043425bb815Sopenharmony_ci 3044425bb815Sopenharmony_ci lexer_next_token (context_p); 3045425bb815Sopenharmony_ci parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); 3046425bb815Sopenharmony_ci 3047425bb815Sopenharmony_ci if (context_p->token.type != LEXER_RIGHT_SQUARE) 3048425bb815Sopenharmony_ci { 3049425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_RIGHT_SQUARE_EXPECTED); 3050425bb815Sopenharmony_ci } 3051425bb815Sopenharmony_ci return; 3052425bb815Sopenharmony_ci } 3053425bb815Sopenharmony_ci case LIT_CHAR_ASTERISK: 3054425bb815Sopenharmony_ci { 3055425bb815Sopenharmony_ci if (ident_opts & (LEXER_OBJ_IDENT_ONLY_IDENTIFIERS | LEXER_OBJ_IDENT_OBJECT_PATTERN)) 3056425bb815Sopenharmony_ci { 3057425bb815Sopenharmony_ci break; 3058425bb815Sopenharmony_ci } 3059425bb815Sopenharmony_ci 3060425bb815Sopenharmony_ci context_p->token.type = LEXER_MULTIPLY; 3061425bb815Sopenharmony_ci lexer_consume_next_character (context_p); 3062425bb815Sopenharmony_ci return; 3063425bb815Sopenharmony_ci } 3064425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 3065425bb815Sopenharmony_ci case LIT_CHAR_RIGHT_BRACE: 3066425bb815Sopenharmony_ci { 3067425bb815Sopenharmony_ci if (ident_opts & LEXER_OBJ_IDENT_ONLY_IDENTIFIERS) 3068425bb815Sopenharmony_ci { 3069425bb815Sopenharmony_ci break; 3070425bb815Sopenharmony_ci } 3071425bb815Sopenharmony_ci 3072425bb815Sopenharmony_ci context_p->token.type = LEXER_RIGHT_BRACE; 3073425bb815Sopenharmony_ci lexer_consume_next_character (context_p); 3074425bb815Sopenharmony_ci return; 3075425bb815Sopenharmony_ci } 3076425bb815Sopenharmony_ci default: 3077425bb815Sopenharmony_ci { 3078425bb815Sopenharmony_ci const uint8_t *char_p = context_p->source_p; 3079425bb815Sopenharmony_ci 3080425bb815Sopenharmony_ci if (char_p[0] == LIT_CHAR_DOT) 3081425bb815Sopenharmony_ci { 3082425bb815Sopenharmony_ci char_p++; 3083425bb815Sopenharmony_ci } 3084425bb815Sopenharmony_ci 3085425bb815Sopenharmony_ci if (char_p < context_p->source_end_p 3086425bb815Sopenharmony_ci && char_p[0] >= LIT_CHAR_0 3087425bb815Sopenharmony_ci && char_p[0] <= LIT_CHAR_9) 3088425bb815Sopenharmony_ci { 3089425bb815Sopenharmony_ci lexer_parse_number (context_p); 3090425bb815Sopenharmony_ci lexer_construct_number_object (context_p, false, false); 3091425bb815Sopenharmony_ci return; 3092425bb815Sopenharmony_ci } 3093425bb815Sopenharmony_ci break; 3094425bb815Sopenharmony_ci } 3095425bb815Sopenharmony_ci } 3096425bb815Sopenharmony_ci } 3097425bb815Sopenharmony_ci 3098425bb815Sopenharmony_ci if (create_literal_object) 3099425bb815Sopenharmony_ci { 3100425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 3101425bb815Sopenharmony_ci if (is_class_method && lexer_compare_literal_to_string (context_p, "constructor", 11)) 3102425bb815Sopenharmony_ci { 3103425bb815Sopenharmony_ci context_p->token.type = LEXER_CLASS_CONSTRUCTOR; 3104425bb815Sopenharmony_ci context_p->token.flags &= (uint8_t) ~LEXER_NO_SKIP_SPACES; 3105425bb815Sopenharmony_ci return; 3106425bb815Sopenharmony_ci } 3107425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 3108425bb815Sopenharmony_ci 3109425bb815Sopenharmony_ci lexer_construct_literal_object (context_p, 3110425bb815Sopenharmony_ci &context_p->token.lit_location, 3111425bb815Sopenharmony_ci LEXER_STRING_LITERAL); 3112425bb815Sopenharmony_ci return; 3113425bb815Sopenharmony_ci } 3114425bb815Sopenharmony_ci 3115425bb815Sopenharmony_ci parser_raise_error (context_p, PARSER_ERR_PROPERTY_IDENTIFIER_EXPECTED); 3116425bb815Sopenharmony_ci} /* lexer_expect_object_literal_id */ 3117425bb815Sopenharmony_ci 3118425bb815Sopenharmony_ci/** 3119425bb815Sopenharmony_ci * Read next token without checking keywords 3120425bb815Sopenharmony_ci * 3121425bb815Sopenharmony_ci * @return true if the next literal is identifier, false otherwise 3122425bb815Sopenharmony_ci */ 3123425bb815Sopenharmony_cibool 3124425bb815Sopenharmony_cilexer_scan_identifier (parser_context_t *context_p) /**< context */ 3125425bb815Sopenharmony_ci{ 3126425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 3127425bb815Sopenharmony_ci context_p->token.line = context_p->line; 3128425bb815Sopenharmony_ci context_p->token.column = context_p->column; 3129425bb815Sopenharmony_ci 3130425bb815Sopenharmony_ci if (context_p->source_p < context_p->source_end_p 3131425bb815Sopenharmony_ci && lexer_parse_identifier (context_p, LEXER_PARSE_NO_OPTS)) 3132425bb815Sopenharmony_ci { 3133425bb815Sopenharmony_ci return true; 3134425bb815Sopenharmony_ci } 3135425bb815Sopenharmony_ci 3136425bb815Sopenharmony_ci lexer_next_token (context_p); 3137425bb815Sopenharmony_ci return false; 3138425bb815Sopenharmony_ci} /* lexer_scan_identifier */ 3139425bb815Sopenharmony_ci 3140425bb815Sopenharmony_ci/** 3141425bb815Sopenharmony_ci * Check whether the identifier is a modifier in a property definition. 3142425bb815Sopenharmony_ci */ 3143425bb815Sopenharmony_civoid 3144425bb815Sopenharmony_cilexer_check_property_modifier (parser_context_t *context_p) /**< context */ 3145425bb815Sopenharmony_ci{ 3146425bb815Sopenharmony_ci JERRY_ASSERT (!(context_p->token.flags & LEXER_NO_SKIP_SPACES)); 3147425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type = LEXER_LITERAL 3148425bb815Sopenharmony_ci && context_p->token.lit_location.type == LEXER_IDENT_LITERAL); 3149425bb815Sopenharmony_ci 3150425bb815Sopenharmony_ci lexer_skip_spaces (context_p); 3151425bb815Sopenharmony_ci context_p->token.flags = (uint8_t) (context_p->token.flags | LEXER_NO_SKIP_SPACES); 3152425bb815Sopenharmony_ci 3153425bb815Sopenharmony_ci if (context_p->source_p >= context_p->source_end_p 3154425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 3155425bb815Sopenharmony_ci || context_p->source_p[0] == LIT_CHAR_COMMA 3156425bb815Sopenharmony_ci || context_p->source_p[0] == LIT_CHAR_RIGHT_BRACE 3157425bb815Sopenharmony_ci || context_p->source_p[0] == LIT_CHAR_LEFT_PAREN 3158425bb815Sopenharmony_ci || context_p->source_p[0] == LIT_CHAR_EQUALS 3159425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 3160425bb815Sopenharmony_ci || context_p->source_p[0] == LIT_CHAR_COLON) 3161425bb815Sopenharmony_ci { 3162425bb815Sopenharmony_ci return; 3163425bb815Sopenharmony_ci } 3164425bb815Sopenharmony_ci 3165425bb815Sopenharmony_ci if (lexer_compare_literal_to_string (context_p, "get", 3)) 3166425bb815Sopenharmony_ci { 3167425bb815Sopenharmony_ci context_p->token.type = LEXER_PROPERTY_GETTER; 3168425bb815Sopenharmony_ci return; 3169425bb815Sopenharmony_ci } 3170425bb815Sopenharmony_ci 3171425bb815Sopenharmony_ci if (lexer_compare_literal_to_string (context_p, "set", 3)) 3172425bb815Sopenharmony_ci { 3173425bb815Sopenharmony_ci context_p->token.type = LEXER_PROPERTY_SETTER; 3174425bb815Sopenharmony_ci return; 3175425bb815Sopenharmony_ci } 3176425bb815Sopenharmony_ci 3177425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 3178425bb815Sopenharmony_ci if (lexer_compare_literal_to_string (context_p, "async", 5)) 3179425bb815Sopenharmony_ci { 3180425bb815Sopenharmony_ci context_p->token.type = LEXER_KEYW_ASYNC; 3181425bb815Sopenharmony_ci return; 3182425bb815Sopenharmony_ci } 3183425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 3184425bb815Sopenharmony_ci} /* lexer_check_property_modifier */ 3185425bb815Sopenharmony_ci 3186425bb815Sopenharmony_ci/** 3187425bb815Sopenharmony_ci * Compares two identifiers. 3188425bb815Sopenharmony_ci * 3189425bb815Sopenharmony_ci * Note: 3190425bb815Sopenharmony_ci * Escape sequences are allowed in the left identifier, but not in the right 3191425bb815Sopenharmony_ci * 3192425bb815Sopenharmony_ci * @return true if the two identifiers are the same 3193425bb815Sopenharmony_ci */ 3194425bb815Sopenharmony_cistatic bool 3195425bb815Sopenharmony_cilexer_compare_identifier_to_chars (const uint8_t *left_p, /**< left identifier */ 3196425bb815Sopenharmony_ci const uint8_t *right_p, /**< right identifier string */ 3197425bb815Sopenharmony_ci size_t size) /**< byte size of the two identifiers */ 3198425bb815Sopenharmony_ci{ 3199425bb815Sopenharmony_ci uint8_t utf8_buf[6]; 3200425bb815Sopenharmony_ci 3201425bb815Sopenharmony_ci do 3202425bb815Sopenharmony_ci { 3203425bb815Sopenharmony_ci if (*left_p == *right_p) 3204425bb815Sopenharmony_ci { 3205425bb815Sopenharmony_ci left_p++; 3206425bb815Sopenharmony_ci right_p++; 3207425bb815Sopenharmony_ci size--; 3208425bb815Sopenharmony_ci continue; 3209425bb815Sopenharmony_ci } 3210425bb815Sopenharmony_ci 3211425bb815Sopenharmony_ci size_t escape_size; 3212425bb815Sopenharmony_ci 3213425bb815Sopenharmony_ci if (*left_p == LIT_CHAR_BACKSLASH) 3214425bb815Sopenharmony_ci { 3215425bb815Sopenharmony_ci left_p += 2; 3216425bb815Sopenharmony_ci lit_code_point_t code_point = lexer_unchecked_hex_to_character (&left_p); 3217425bb815Sopenharmony_ci 3218425bb815Sopenharmony_ci escape_size = lit_code_point_to_cesu8_bytes (utf8_buf, code_point); 3219425bb815Sopenharmony_ci } 3220425bb815Sopenharmony_ci else if (*left_p >= LIT_UTF8_4_BYTE_MARKER) 3221425bb815Sopenharmony_ci { 3222425bb815Sopenharmony_ci lit_four_byte_utf8_char_to_cesu8 (utf8_buf, left_p); 3223425bb815Sopenharmony_ci escape_size = 3 * 2; 3224425bb815Sopenharmony_ci left_p += 4; 3225425bb815Sopenharmony_ci } 3226425bb815Sopenharmony_ci else 3227425bb815Sopenharmony_ci { 3228425bb815Sopenharmony_ci return false; 3229425bb815Sopenharmony_ci } 3230425bb815Sopenharmony_ci 3231425bb815Sopenharmony_ci size -= escape_size; 3232425bb815Sopenharmony_ci 3233425bb815Sopenharmony_ci uint8_t *utf8_p = utf8_buf; 3234425bb815Sopenharmony_ci do 3235425bb815Sopenharmony_ci { 3236425bb815Sopenharmony_ci if (*right_p++ != *utf8_p++) 3237425bb815Sopenharmony_ci { 3238425bb815Sopenharmony_ci return false; 3239425bb815Sopenharmony_ci } 3240425bb815Sopenharmony_ci } 3241425bb815Sopenharmony_ci while (--escape_size > 0); 3242425bb815Sopenharmony_ci } 3243425bb815Sopenharmony_ci while (size > 0); 3244425bb815Sopenharmony_ci 3245425bb815Sopenharmony_ci return true; 3246425bb815Sopenharmony_ci} /* lexer_compare_identifier_to_chars */ 3247425bb815Sopenharmony_ci 3248425bb815Sopenharmony_ci/** 3249425bb815Sopenharmony_ci * Compares an identifier to a string. 3250425bb815Sopenharmony_ci * 3251425bb815Sopenharmony_ci * Note: 3252425bb815Sopenharmony_ci * Escape sequences are allowed in the left identifier, but not in the right 3253425bb815Sopenharmony_ci * 3254425bb815Sopenharmony_ci * @return true if the identifier equals to string 3255425bb815Sopenharmony_ci */ 3256425bb815Sopenharmony_cibool 3257425bb815Sopenharmony_cilexer_compare_identifier_to_string (const lexer_lit_location_t *left_p, /**< left literal */ 3258425bb815Sopenharmony_ci const uint8_t *right_p, /**< right identifier string */ 3259425bb815Sopenharmony_ci size_t size) /**< byte size of the right identifier */ 3260425bb815Sopenharmony_ci{ 3261425bb815Sopenharmony_ci if (left_p->length != size) 3262425bb815Sopenharmony_ci { 3263425bb815Sopenharmony_ci return false; 3264425bb815Sopenharmony_ci } 3265425bb815Sopenharmony_ci 3266425bb815Sopenharmony_ci if (!left_p->has_escape) 3267425bb815Sopenharmony_ci { 3268425bb815Sopenharmony_ci return memcmp (left_p->char_p, right_p, size) == 0; 3269425bb815Sopenharmony_ci } 3270425bb815Sopenharmony_ci 3271425bb815Sopenharmony_ci return lexer_compare_identifier_to_chars (left_p->char_p, right_p, size); 3272425bb815Sopenharmony_ci} /* lexer_compare_identifier_to_string */ 3273425bb815Sopenharmony_ci 3274425bb815Sopenharmony_ci/** 3275425bb815Sopenharmony_ci * Compares two identifiers. 3276425bb815Sopenharmony_ci * 3277425bb815Sopenharmony_ci * Note: 3278425bb815Sopenharmony_ci * Escape sequences are allowed in both identifiers 3279425bb815Sopenharmony_ci * 3280425bb815Sopenharmony_ci * @return true if the two identifiers are the same 3281425bb815Sopenharmony_ci */ 3282425bb815Sopenharmony_cibool 3283425bb815Sopenharmony_cilexer_compare_identifiers (parser_context_t *context_p, /**< context */ 3284425bb815Sopenharmony_ci const lexer_lit_location_t *left_p, /**< left literal */ 3285425bb815Sopenharmony_ci const lexer_lit_location_t *right_p) /**< right literal */ 3286425bb815Sopenharmony_ci{ 3287425bb815Sopenharmony_ci prop_length_t length = left_p->length; 3288425bb815Sopenharmony_ci 3289425bb815Sopenharmony_ci if (length != right_p->length) 3290425bb815Sopenharmony_ci { 3291425bb815Sopenharmony_ci return false; 3292425bb815Sopenharmony_ci } 3293425bb815Sopenharmony_ci 3294425bb815Sopenharmony_ci if (!left_p->has_escape) 3295425bb815Sopenharmony_ci { 3296425bb815Sopenharmony_ci return lexer_compare_identifier_to_chars (right_p->char_p, left_p->char_p, length); 3297425bb815Sopenharmony_ci } 3298425bb815Sopenharmony_ci 3299425bb815Sopenharmony_ci if (!right_p->has_escape) 3300425bb815Sopenharmony_ci { 3301425bb815Sopenharmony_ci return lexer_compare_identifier_to_chars (left_p->char_p, right_p->char_p, length); 3302425bb815Sopenharmony_ci } 3303425bb815Sopenharmony_ci 3304425bb815Sopenharmony_ci uint8_t buf_p[64]; 3305425bb815Sopenharmony_ci 3306425bb815Sopenharmony_ci if (length <= 64) 3307425bb815Sopenharmony_ci { 3308425bb815Sopenharmony_ci lexer_convert_ident_to_cesu8 (buf_p, left_p->char_p, length); 3309425bb815Sopenharmony_ci return lexer_compare_identifier_to_chars (right_p->char_p, buf_p, length); 3310425bb815Sopenharmony_ci } 3311425bb815Sopenharmony_ci 3312425bb815Sopenharmony_ci uint8_t *dynamic_buf_p = parser_malloc (context_p, length); 3313425bb815Sopenharmony_ci 3314425bb815Sopenharmony_ci lexer_convert_ident_to_cesu8 (dynamic_buf_p, left_p->char_p, length); 3315425bb815Sopenharmony_ci bool result = lexer_compare_identifier_to_chars (right_p->char_p, dynamic_buf_p, length); 3316425bb815Sopenharmony_ci parser_free (dynamic_buf_p, length); 3317425bb815Sopenharmony_ci 3318425bb815Sopenharmony_ci return result; 3319425bb815Sopenharmony_ci} /* lexer_compare_identifiers */ 3320425bb815Sopenharmony_ci 3321425bb815Sopenharmony_ci/** 3322425bb815Sopenharmony_ci * Compares the current identifier in the context to the parameter identifier 3323425bb815Sopenharmony_ci * 3324425bb815Sopenharmony_ci * Note: 3325425bb815Sopenharmony_ci * Escape sequences are allowed. 3326425bb815Sopenharmony_ci * 3327425bb815Sopenharmony_ci * @return true if the input identifiers are the same 3328425bb815Sopenharmony_ci */ 3329425bb815Sopenharmony_cibool 3330425bb815Sopenharmony_cilexer_current_is_literal (parser_context_t *context_p, /**< context */ 3331425bb815Sopenharmony_ci const lexer_lit_location_t *right_ident_p) /**< identifier */ 3332425bb815Sopenharmony_ci{ 3333425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LITERAL 3334425bb815Sopenharmony_ci && context_p->token.lit_location.type == LEXER_IDENT_LITERAL); 3335425bb815Sopenharmony_ci 3336425bb815Sopenharmony_ci lexer_lit_location_t *left_ident_p = &context_p->token.lit_location; 3337425bb815Sopenharmony_ci 3338425bb815Sopenharmony_ci JERRY_ASSERT (left_ident_p->length > 0 && right_ident_p->length > 0); 3339425bb815Sopenharmony_ci 3340425bb815Sopenharmony_ci if (left_ident_p->length != right_ident_p->length) 3341425bb815Sopenharmony_ci { 3342425bb815Sopenharmony_ci return false; 3343425bb815Sopenharmony_ci } 3344425bb815Sopenharmony_ci 3345425bb815Sopenharmony_ci if (!left_ident_p->has_escape && !right_ident_p->has_escape) 3346425bb815Sopenharmony_ci { 3347425bb815Sopenharmony_ci return memcmp (left_ident_p->char_p, right_ident_p->char_p, left_ident_p->length) == 0; 3348425bb815Sopenharmony_ci } 3349425bb815Sopenharmony_ci 3350425bb815Sopenharmony_ci return lexer_compare_identifiers (context_p, left_ident_p, right_ident_p); 3351425bb815Sopenharmony_ci} /* lexer_current_is_literal */ 3352425bb815Sopenharmony_ci 3353425bb815Sopenharmony_ci/** 3354425bb815Sopenharmony_ci * Compares the current string token to "use strict". 3355425bb815Sopenharmony_ci * 3356425bb815Sopenharmony_ci * Note: 3357425bb815Sopenharmony_ci * Escape sequences are not allowed. 3358425bb815Sopenharmony_ci * 3359425bb815Sopenharmony_ci * @return true if "use strict" is found, false otherwise 3360425bb815Sopenharmony_ci */ 3361425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 3362425bb815Sopenharmony_cilexer_string_is_use_strict (parser_context_t *context_p) /**< context */ 3363425bb815Sopenharmony_ci{ 3364425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LITERAL 3365425bb815Sopenharmony_ci && context_p->token.lit_location.type == LEXER_STRING_LITERAL); 3366425bb815Sopenharmony_ci 3367425bb815Sopenharmony_ci return (context_p->token.lit_location.length == 10 3368425bb815Sopenharmony_ci && !context_p->token.lit_location.has_escape 3369425bb815Sopenharmony_ci && memcmp (context_p->token.lit_location.char_p, "use strict", 10) == 0); 3370425bb815Sopenharmony_ci} /* lexer_string_is_use_strict */ 3371425bb815Sopenharmony_ci 3372425bb815Sopenharmony_ci/** 3373425bb815Sopenharmony_ci * Checks whether the string before the current token is a directive or a string literal. 3374425bb815Sopenharmony_ci * 3375425bb815Sopenharmony_ci * @return true if the string is a directive, false otherwise 3376425bb815Sopenharmony_ci */ 3377425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 3378425bb815Sopenharmony_cilexer_string_is_directive (parser_context_t *context_p) /**< context */ 3379425bb815Sopenharmony_ci{ 3380425bb815Sopenharmony_ci return (context_p->token.type == LEXER_SEMICOLON 3381425bb815Sopenharmony_ci || context_p->token.type == LEXER_RIGHT_BRACE 3382425bb815Sopenharmony_ci || ((context_p->token.flags & LEXER_WAS_NEWLINE) 3383425bb815Sopenharmony_ci && !LEXER_IS_BINARY_OP_TOKEN (context_p->token.type) 3384425bb815Sopenharmony_ci && context_p->token.type != LEXER_LEFT_PAREN 3385425bb815Sopenharmony_ci && context_p->token.type != LEXER_LEFT_SQUARE 3386425bb815Sopenharmony_ci && context_p->token.type != LEXER_DOT)); 3387425bb815Sopenharmony_ci} /* lexer_string_is_directive */ 3388425bb815Sopenharmony_ci 3389425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 3390425bb815Sopenharmony_ci 3391425bb815Sopenharmony_ci/** 3392425bb815Sopenharmony_ci * Compares the current token to an expected identifier. 3393425bb815Sopenharmony_ci * 3394425bb815Sopenharmony_ci * Note: 3395425bb815Sopenharmony_ci * Escape sequences are not allowed. 3396425bb815Sopenharmony_ci * 3397425bb815Sopenharmony_ci * @return true if they are the same, false otherwise 3398425bb815Sopenharmony_ci */ 3399425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 3400425bb815Sopenharmony_cilexer_token_is_identifier (parser_context_t *context_p, /**< context */ 3401425bb815Sopenharmony_ci const char *identifier_p, /**< identifier */ 3402425bb815Sopenharmony_ci size_t identifier_length) /**< identifier length */ 3403425bb815Sopenharmony_ci{ 3404425bb815Sopenharmony_ci /* Checking has_escape is unnecessary because memcmp will fail if escape sequences are present. */ 3405425bb815Sopenharmony_ci return (context_p->token.type == LEXER_LITERAL 3406425bb815Sopenharmony_ci && context_p->token.lit_location.type == LEXER_IDENT_LITERAL 3407425bb815Sopenharmony_ci && context_p->token.lit_location.length == identifier_length 3408425bb815Sopenharmony_ci && memcmp (context_p->token.lit_location.char_p, identifier_p, identifier_length) == 0); 3409425bb815Sopenharmony_ci} /* lexer_token_is_identifier */ 3410425bb815Sopenharmony_ci 3411425bb815Sopenharmony_ci/** 3412425bb815Sopenharmony_ci * Compares the current identifier token to "let". 3413425bb815Sopenharmony_ci * 3414425bb815Sopenharmony_ci * Note: 3415425bb815Sopenharmony_ci * Escape sequences are not allowed. 3416425bb815Sopenharmony_ci * 3417425bb815Sopenharmony_ci * @return true if "let" is found, false otherwise 3418425bb815Sopenharmony_ci */ 3419425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 3420425bb815Sopenharmony_cilexer_token_is_let (parser_context_t *context_p) /**< context */ 3421425bb815Sopenharmony_ci{ 3422425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LITERAL); 3423425bb815Sopenharmony_ci 3424425bb815Sopenharmony_ci return (context_p->token.keyword_type == LEXER_KEYW_LET 3425425bb815Sopenharmony_ci && !context_p->token.lit_location.has_escape); 3426425bb815Sopenharmony_ci} /* lexer_token_is_let */ 3427425bb815Sopenharmony_ci 3428425bb815Sopenharmony_ci/** 3429425bb815Sopenharmony_ci * Compares the current identifier token to "async". 3430425bb815Sopenharmony_ci * 3431425bb815Sopenharmony_ci * Note: 3432425bb815Sopenharmony_ci * Escape sequences are not allowed. 3433425bb815Sopenharmony_ci * 3434425bb815Sopenharmony_ci * @return true if "async" is found, false otherwise 3435425bb815Sopenharmony_ci */ 3436425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 3437425bb815Sopenharmony_cilexer_token_is_async (parser_context_t *context_p) /**< context */ 3438425bb815Sopenharmony_ci{ 3439425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LITERAL 3440425bb815Sopenharmony_ci || context_p->token.type == LEXER_TEMPLATE_LITERAL); 3441425bb815Sopenharmony_ci 3442425bb815Sopenharmony_ci return (context_p->token.keyword_type == LEXER_KEYW_ASYNC 3443425bb815Sopenharmony_ci && !context_p->token.lit_location.has_escape); 3444425bb815Sopenharmony_ci} /* lexer_token_is_async */ 3445425bb815Sopenharmony_ci 3446425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 3447425bb815Sopenharmony_ci 3448425bb815Sopenharmony_ci/** 3449425bb815Sopenharmony_ci * Compares the current identifier or string to an expected string. 3450425bb815Sopenharmony_ci * 3451425bb815Sopenharmony_ci * Note: 3452425bb815Sopenharmony_ci * Escape sequences are not allowed. 3453425bb815Sopenharmony_ci * 3454425bb815Sopenharmony_ci * @return true if they are the same, false otherwise 3455425bb815Sopenharmony_ci */ 3456425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 3457425bb815Sopenharmony_cilexer_compare_literal_to_string (parser_context_t *context_p, /**< context */ 3458425bb815Sopenharmony_ci const char *string_p, /**< string */ 3459425bb815Sopenharmony_ci size_t string_length) /**< string length */ 3460425bb815Sopenharmony_ci{ 3461425bb815Sopenharmony_ci JERRY_ASSERT (context_p->token.type == LEXER_LITERAL 3462425bb815Sopenharmony_ci && (context_p->token.lit_location.type == LEXER_IDENT_LITERAL 3463425bb815Sopenharmony_ci || context_p->token.lit_location.type == LEXER_STRING_LITERAL)); 3464425bb815Sopenharmony_ci 3465425bb815Sopenharmony_ci /* Checking has_escape is unnecessary because memcmp will fail if escape sequences are present. */ 3466425bb815Sopenharmony_ci return (context_p->token.lit_location.length == string_length 3467425bb815Sopenharmony_ci && memcmp (context_p->token.lit_location.char_p, string_p, string_length) == 0); 3468425bb815Sopenharmony_ci} /* lexer_compare_literal_to_string */ 3469425bb815Sopenharmony_ci 3470425bb815Sopenharmony_ci/** 3471425bb815Sopenharmony_ci * Convert binary lvalue token to binary token 3472425bb815Sopenharmony_ci * e.g. += -> + 3473425bb815Sopenharmony_ci * ^= -> ^ 3474425bb815Sopenharmony_ci * 3475425bb815Sopenharmony_ci * @return binary token 3476425bb815Sopenharmony_ci */ 3477425bb815Sopenharmony_ciuint8_t 3478425bb815Sopenharmony_cilexer_convert_binary_lvalue_token_to_binary (uint8_t token) /**< binary lvalue token */ 3479425bb815Sopenharmony_ci{ 3480425bb815Sopenharmony_ci JERRY_ASSERT (LEXER_IS_BINARY_LVALUE_TOKEN (token)); 3481425bb815Sopenharmony_ci JERRY_ASSERT (token != LEXER_ASSIGN); 3482425bb815Sopenharmony_ci 3483425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 3484425bb815Sopenharmony_ci if (token <= LEXER_ASSIGN_EXPONENTIATION) 3485425bb815Sopenharmony_ci { 3486425bb815Sopenharmony_ci return (uint8_t) (LEXER_ADD + (token - LEXER_ASSIGN_ADD)); 3487425bb815Sopenharmony_ci } 3488425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 3489425bb815Sopenharmony_ci if (token <= LEXER_ASSIGN_MODULO) 3490425bb815Sopenharmony_ci { 3491425bb815Sopenharmony_ci return (uint8_t) (LEXER_ADD + (token - LEXER_ASSIGN_ADD)); 3492425bb815Sopenharmony_ci } 3493425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 3494425bb815Sopenharmony_ci 3495425bb815Sopenharmony_ci if (token <= LEXER_ASSIGN_UNS_RIGHT_SHIFT) 3496425bb815Sopenharmony_ci { 3497425bb815Sopenharmony_ci return (uint8_t) (LEXER_LEFT_SHIFT + (token - LEXER_ASSIGN_LEFT_SHIFT)); 3498425bb815Sopenharmony_ci } 3499425bb815Sopenharmony_ci 3500425bb815Sopenharmony_ci switch (token) 3501425bb815Sopenharmony_ci { 3502425bb815Sopenharmony_ci case LEXER_ASSIGN_BIT_AND: 3503425bb815Sopenharmony_ci { 3504425bb815Sopenharmony_ci return LEXER_BIT_AND; 3505425bb815Sopenharmony_ci } 3506425bb815Sopenharmony_ci case LEXER_ASSIGN_BIT_OR: 3507425bb815Sopenharmony_ci { 3508425bb815Sopenharmony_ci return LEXER_BIT_OR; 3509425bb815Sopenharmony_ci } 3510425bb815Sopenharmony_ci default: 3511425bb815Sopenharmony_ci { 3512425bb815Sopenharmony_ci JERRY_ASSERT (token == LEXER_ASSIGN_BIT_XOR); 3513425bb815Sopenharmony_ci return LEXER_BIT_XOR; 3514425bb815Sopenharmony_ci } 3515425bb815Sopenharmony_ci } 3516425bb815Sopenharmony_ci} /* lexer_convert_binary_lvalue_token_to_binary */ 3517425bb815Sopenharmony_ci 3518425bb815Sopenharmony_ci/** 3519425bb815Sopenharmony_ci * @} 3520425bb815Sopenharmony_ci * @} 3521425bb815Sopenharmony_ci * @} 3522425bb815Sopenharmony_ci */ 3523425bb815Sopenharmony_ci 3524425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PARSER) */ 3525