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