Implement the for of statement (#2871)

JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
Robert Fancsik
2019-06-07 06:35:42 -04:00
committed by Dániel Bátyai
parent b6fc4e13ae
commit 343e80053b
15 changed files with 530 additions and 48 deletions
+10 -2
View File
@@ -188,6 +188,8 @@
/* Stack consumption of opcodes with context. */
/* PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION must be <= 3 */
#define PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION 3
/* PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION must be <= 4 */
#define PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION 4
/* PARSER_WITH_CONTEXT_STACK_ALLOCATION must be <= 4 */
@@ -492,6 +494,14 @@
VM_OC_SET_GETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_LITERAL_LITERAL) \
CBC_BACKWARD_BRANCH (CBC_EXT_BRANCH_IF_FOR_IN_HAS_NEXT, 0, \
VM_OC_FOR_IN_HAS_NEXT) \
CBC_OPCODE (CBC_EXT_FOR_OF_GET_NEXT, CBC_NO_FLAG, 1, \
VM_OC_FOR_OF_GET_NEXT | VM_OC_PUT_STACK) \
CBC_FORWARD_BRANCH (CBC_EXT_FOR_OF_CREATE_CONTEXT, \
-1 + PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION, VM_OC_FOR_OF_CREATE_CONTEXT) \
CBC_OPCODE (CBC_EXT_PUSH_NAMED_FUNC_EXPRESSION, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 1, \
VM_OC_PUSH_NAMED_FUNC_EXPR | VM_OC_GET_LITERAL_LITERAL) \
CBC_BACKWARD_BRANCH (CBC_EXT_BRANCH_IF_FOR_OF_HAS_NEXT, 0, \
VM_OC_FOR_OF_HAS_NEXT) \
CBC_OPCODE (CBC_EXT_SET_SETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
VM_OC_SET_SETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_LITERAL_LITERAL) \
CBC_FORWARD_BRANCH (CBC_EXT_TRY_CREATE_CONTEXT, PARSER_TRY_CONTEXT_STACK_ALLOCATION, \
@@ -510,8 +520,6 @@
-1 + PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION, VM_OC_CLASS_HERITAGE) \
\
/* Basic opcodes. */ \
CBC_OPCODE (CBC_EXT_PUSH_NAMED_FUNC_EXPRESSION, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 1, \
VM_OC_PUSH_NAMED_FUNC_EXPR | VM_OC_GET_LITERAL_LITERAL) \
CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0, CBC_HAS_LITERAL_ARG, 2, \
VM_OC_PUSH_LIT_0 | VM_OC_GET_LITERAL) \
CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE, CBC_HAS_LITERAL_ARG | CBC_HAS_BYTE_ARG, 2, \
+4
View File
@@ -153,6 +153,10 @@ typedef enum
LEXER_COMMA_SEP_LIST, /**< comma separated bracketed expression list */
LEXER_SCAN_SWITCH, /**< special value for switch pre-scan */
LEXER_CLASS_CONSTRUCTOR, /**< special value for class constructor method */
#if ENABLED (JERRY_ES2015_FOR_OF)
LEXER_FOR_IN_OF, /**< special value during for in/of statmenet scanning */
LEXER_LITERAL_OF, /**< 'of' literal */
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
#if !ENABLED (JERRY_ES2015)
/* Future reserved words: these keywords
+31 -5
View File
@@ -675,7 +675,13 @@ parser_scan_until (parser_context_t *context_p, /**< context */
{
lexer_next_token (context_p);
if (end_type == LEXER_KEYW_IN)
#if ENABLED (JERRY_ES2015_FOR_OF)
lexer_token_type_t for_in_of_token = LEXER_FOR_IN_OF;
#else /* !ENABLED (JERRY_ES2015_FOR_OF) */
lexer_token_type_t for_in_of_token = LEXER_KEYW_IN;
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
if (end_type == for_in_of_token)
{
end_type_b = LEXER_SEMICOLON;
if (context_p->token.type == LEXER_KEYW_VAR)
@@ -697,11 +703,31 @@ parser_scan_until (parser_context_t *context_p, /**< context */
parser_raise_error (context_p, PARSER_ERR_EXPRESSION_EXPECTED);
}
if (stack_top == SCAN_STACK_HEAD
&& (type == end_type || type == end_type_b))
if (stack_top == SCAN_STACK_HEAD)
{
parser_stack_pop_uint8 (context_p);
return;
if (type == end_type || type == end_type_b)
{
parser_stack_pop_uint8 (context_p);
return;
}
#if ENABLED (JERRY_ES2015_FOR_OF)
if (end_type == LEXER_FOR_IN_OF)
{
if (type == LEXER_KEYW_IN)
{
parser_stack_pop_uint8 (context_p);
context_p->token.type = LEXER_KEYW_IN;
return;
}
else if (type == LEXER_LITERAL && lexer_compare_raw_identifier_to_current (context_p, "of", 2))
{
parser_stack_pop_uint8 (context_p);
context_p->token.type = LEXER_LITERAL_OF;
return;
}
}
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
}
switch (mode)
+234 -39
View File
@@ -21,6 +21,13 @@
#include "ecma-helpers.h"
#include "lit-char-helpers.h"
#if ENABLED (JERRY_ES2015_FOR_OF)
#if !ENABLED (JERRY_ES2015_BUILTIN_ITERATOR)
#error "For of support requires ES2015 iterator support"
#endif /* !ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
/** \addtogroup parser Parser
* @{
*
@@ -71,6 +78,9 @@ typedef enum
* Break and continue uses another instruction form
* when crosses their borders. */
PARSER_STATEMENT_FOR_IN,
#if ENABLED (JERRY_ES2015_FOR_OF)
PARSER_STATEMENT_FOR_OF,
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
PARSER_STATEMENT_WITH,
PARSER_STATEMENT_TRY,
} parser_statement_type_t;
@@ -147,6 +157,17 @@ typedef struct
uint32_t start_offset; /**< start byte code offset */
} parser_for_in_statement_t;
#if ENABLED (JERRY_ES2015_FOR_OF)
/**
* For-of statement.
*/
typedef struct
{
parser_branch_t branch; /**< branch to the end */
uint32_t start_offset; /**< start byte code offset */
} parser_for_of_statement_t;
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
/**
* With statement.
*/
@@ -183,7 +204,7 @@ typedef struct
static inline size_t
parser_statement_length (uint8_t type) /**< type of statement */
{
static const uint8_t statement_lengths[12] =
static const uint8_t statement_lengths[] =
{
/* PARSER_STATEMENT_BLOCK */
1,
@@ -205,6 +226,10 @@ parser_statement_length (uint8_t type) /**< type of statement */
(uint8_t) (sizeof (parser_for_statement_t) + sizeof (parser_loop_statement_t) + 1),
/* PARSER_STATEMENT_FOR_IN */
(uint8_t) (sizeof (parser_for_in_statement_t) + sizeof (parser_loop_statement_t) + 1),
#if ENABLED (JERRY_ES2015_FOR_OF)
/* PARSER_STATEMENT_FOR_OF */
(uint8_t) (sizeof (parser_for_of_statement_t) + sizeof (parser_loop_statement_t) + 1),
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
/* PARSER_STATEMENT_WITH */
(uint8_t) (sizeof (parser_with_statement_t) + 1),
/* PARSER_STATEMENT_TRY */
@@ -212,7 +237,6 @@ parser_statement_length (uint8_t type) /**< type of statement */
};
JERRY_ASSERT (type >= PARSER_STATEMENT_BLOCK && type <= PARSER_STATEMENT_TRY);
JERRY_ASSERT (PARSER_STATEMENT_TRY - PARSER_STATEMENT_BLOCK == 11);
return statement_lengths[type - PARSER_STATEMENT_BLOCK];
} /* parser_statement_length */
@@ -837,6 +861,52 @@ parser_parse_while_statement_end (parser_context_t *context_p) /**< context */
context_p->token = current_token;
} /* parser_parse_while_statement_end */
/**
* Check whether the opcode is a valid LeftHandSide expression
* and convert it back to an assignment.
*
* @return the compatible assignment opcode
*/
static uint16_t
parser_check_left_hand_side_expression (parser_context_t *context_p, /**< context */
uint16_t opcode) /**< opcode to check */
{
if (opcode == CBC_PUSH_LITERAL
&& context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
{
context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
return CBC_ASSIGN_SET_IDENT;
}
else if (opcode == CBC_PUSH_PROP)
{
context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
return CBC_ASSIGN;
}
else if (opcode == CBC_PUSH_PROP_LITERAL)
{
context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
return CBC_ASSIGN_PROP_LITERAL;
}
else if (opcode == CBC_PUSH_PROP_LITERAL_LITERAL)
{
context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
return CBC_ASSIGN;
}
else if (opcode == CBC_PUSH_PROP_THIS_LITERAL)
{
context_p->last_cbc_opcode = CBC_PUSH_THIS_LITERAL;
return CBC_ASSIGN;
}
else
{
/* Invalid LeftHandSide expression. */
parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
return CBC_ASSIGN;
}
return opcode;
} /* parser_check_left_hand_side_expression */
/**
* Parse for statement (starting part).
*/
@@ -854,7 +924,13 @@ parser_parse_for_statement_start (parser_context_t *context_p) /**< context */
parser_raise_error (context_p, PARSER_ERR_LEFT_PAREN_EXPECTED);
}
parser_scan_until (context_p, &start_range, LEXER_KEYW_IN);
#if ENABLED (JERRY_ES2015_FOR_OF)
lexer_token_type_t scan_token = LEXER_FOR_IN_OF;
#else /* !ENABLED (JERRY_ES2015_FOR_OF) */
lexer_token_type_t scan_token = LEXER_KEYW_IN;
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
parser_scan_until (context_p, &start_range, scan_token);
if (context_p->token.type == LEXER_KEYW_IN)
{
@@ -925,38 +1001,7 @@ parser_parse_for_statement_start (parser_context_t *context_p) /**< context */
JERRY_ASSERT (opcode != CBC_PUSH_TWO_LITERALS
&& opcode != CBC_PUSH_THREE_LITERALS);
if (opcode == CBC_PUSH_LITERAL
&& context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
{
opcode = CBC_ASSIGN_SET_IDENT;
context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
}
else if (opcode == CBC_PUSH_PROP)
{
opcode = CBC_ASSIGN;
context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
}
else if (opcode == CBC_PUSH_PROP_LITERAL)
{
opcode = CBC_ASSIGN_PROP_LITERAL;
context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
}
else if (opcode == CBC_PUSH_PROP_LITERAL_LITERAL)
{
opcode = CBC_ASSIGN;
context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
}
else if (opcode == CBC_PUSH_PROP_THIS_LITERAL)
{
opcode = CBC_ASSIGN;
context_p->last_cbc_opcode = CBC_PUSH_THIS_LITERAL;
}
else
{
/* Invalid LeftHandSide expression. */
parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
opcode = CBC_ASSIGN;
}
opcode = parser_check_left_hand_side_expression (context_p, opcode);
parser_emit_cbc_ext (context_p, CBC_EXT_FOR_IN_GET_NEXT);
parser_flush_cbc (context_p);
@@ -980,6 +1025,101 @@ parser_parse_for_statement_start (parser_context_t *context_p) /**< context */
parser_stack_push_uint8 (context_p, PARSER_STATEMENT_FOR_IN);
parser_stack_iterator_init (context_p, &context_p->last_statement);
}
#if ENABLED (JERRY_ES2015_FOR_OF)
else if (context_p->token.type == LEXER_LITERAL_OF)
{
parser_for_of_statement_t for_of_statement;
lexer_range_t range;
lexer_next_token (context_p);
parser_parse_expression (context_p, PARSE_EXPR);
if (context_p->token.type != LEXER_RIGHT_PAREN)
{
parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
}
#ifndef JERRY_NDEBUG
PARSER_PLUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION);
#endif /* !JERRY_NDEBUG */
parser_emit_cbc_ext_forward_branch (context_p,
CBC_EXT_FOR_OF_CREATE_CONTEXT,
&for_of_statement.branch);
JERRY_ASSERT (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE);
for_of_statement.start_offset = context_p->byte_code_size;
parser_save_range (context_p, &range, context_p->source_end_p);
parser_set_range (context_p, &start_range);
lexer_next_token (context_p);
if (context_p->token.type == LEXER_KEYW_VAR)
{
uint16_t literal_index;
lexer_expect_identifier (context_p, LEXER_IDENT_LITERAL);
JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
&& context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_VAR;
literal_index = context_p->lit_object.index;
lexer_next_token (context_p);
if (context_p->token.type == LEXER_ASSIGN)
{
parser_branch_t branch;
/* Initialiser is never executed. */
parser_emit_cbc_forward_branch (context_p, CBC_JUMP_FORWARD, &branch);
lexer_next_token (context_p);
parser_parse_expression (context_p,
PARSE_EXPR_STATEMENT | PARSE_EXPR_NO_COMMA);
parser_set_branch_to_current_position (context_p, &branch);
}
parser_emit_cbc_ext (context_p, CBC_EXT_FOR_OF_GET_NEXT);
parser_emit_cbc_literal (context_p, CBC_ASSIGN_SET_IDENT, literal_index);
}
else
{
uint16_t opcode;
parser_parse_expression (context_p, PARSE_EXPR);
opcode = context_p->last_cbc_opcode;
/* The CBC_EXT_FOR_OF_CREATE_CONTEXT flushed the opcode combiner. */
JERRY_ASSERT (opcode != CBC_PUSH_TWO_LITERALS
&& opcode != CBC_PUSH_THREE_LITERALS);
opcode = parser_check_left_hand_side_expression (context_p, opcode);
parser_emit_cbc_ext (context_p, CBC_EXT_FOR_OF_GET_NEXT);
parser_flush_cbc (context_p);
context_p->last_cbc_opcode = opcode;
}
if (context_p->token.type != LEXER_EOS)
{
parser_raise_error (context_p, PARSER_ERR_OF_EXPECTED);
}
parser_flush_cbc (context_p);
parser_set_range (context_p, &range);
lexer_next_token (context_p);
loop.branch_list_p = NULL;
parser_stack_push (context_p, &for_of_statement, sizeof (parser_for_of_statement_t));
parser_stack_push (context_p, &loop, sizeof (parser_loop_statement_t));
parser_stack_push_uint8 (context_p, PARSER_STATEMENT_FOR_OF);
parser_stack_iterator_init (context_p, &context_p->last_statement);
}
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
else
{
parser_for_statement_t for_statement;
@@ -1482,6 +1622,9 @@ parser_parse_break_statement (parser_context_t *context_p) /**< context */
}
if (type == PARSER_STATEMENT_FOR_IN
#if ENABLED (JERRY_ES2015_FOR_OF)
|| type == PARSER_STATEMENT_FOR_OF
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
|| type == PARSER_STATEMENT_WITH
|| type == PARSER_STATEMENT_TRY)
{
@@ -1523,6 +1666,9 @@ parser_parse_break_statement (parser_context_t *context_p) /**< context */
}
if (type == PARSER_STATEMENT_FOR_IN
#if ENABLED (JERRY_ES2015_FOR_OF)
|| type == PARSER_STATEMENT_FOR_OF
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
|| type == PARSER_STATEMENT_WITH
|| type == PARSER_STATEMENT_TRY)
{
@@ -1534,6 +1680,9 @@ parser_parse_break_statement (parser_context_t *context_p) /**< context */
|| type == PARSER_STATEMENT_DO_WHILE
|| type == PARSER_STATEMENT_WHILE
|| type == PARSER_STATEMENT_FOR
#if ENABLED (JERRY_ES2015_FOR_OF)
|| type == PARSER_STATEMENT_FOR_OF
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
|| type == PARSER_STATEMENT_FOR_IN)
{
parser_loop_statement_t loop;
@@ -1568,7 +1717,7 @@ parser_parse_continue_statement (parser_context_t *context_p) /**< context */
&& context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
{
parser_stack_iterator_t loop_iterator;
bool for_in_was_seen = false;
bool for_in_of_was_seen = false;
loop_iterator.current_p = NULL;
@@ -1608,20 +1757,29 @@ parser_parse_continue_statement (parser_context_t *context_p) /**< context */
continue;
}
#if ENABLED (JERRY_ES2015_FOR_OF)
bool is_for_in_of_statement = (type == PARSER_STATEMENT_FOR_IN) || (type == PARSER_STATEMENT_FOR_OF);
#else /* !ENABLED (JERRY_ES2015_FOR_OF) */
bool is_for_in_of_statement = (type == PARSER_STATEMENT_FOR_IN);
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
if (type == PARSER_STATEMENT_WITH
|| type == PARSER_STATEMENT_TRY
|| for_in_was_seen)
|| for_in_of_was_seen)
{
opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT;
}
else if (type == PARSER_STATEMENT_FOR_IN)
else if (is_for_in_of_statement)
{
for_in_was_seen = true;
for_in_of_was_seen = true;
}
if (type == PARSER_STATEMENT_DO_WHILE
|| type == PARSER_STATEMENT_WHILE
|| type == PARSER_STATEMENT_FOR
#if ENABLED (JERRY_ES2015_FOR_OF)
|| type == PARSER_STATEMENT_FOR_OF
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
|| type == PARSER_STATEMENT_FOR_IN)
{
loop_iterator = iterator;
@@ -1647,6 +1805,9 @@ parser_parse_continue_statement (parser_context_t *context_p) /**< context */
if (type == PARSER_STATEMENT_DO_WHILE
|| type == PARSER_STATEMENT_WHILE
|| type == PARSER_STATEMENT_FOR
#if ENABLED (JERRY_ES2015_FOR_OF)
|| type == PARSER_STATEMENT_FOR_OF
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
|| type == PARSER_STATEMENT_FOR_IN)
{
parser_loop_statement_t loop;
@@ -2182,6 +2343,9 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
|| context_p->stack_top_uint8 == PARSER_STATEMENT_WHILE
|| context_p->stack_top_uint8 == PARSER_STATEMENT_FOR
|| context_p->stack_top_uint8 == PARSER_STATEMENT_FOR_IN
#if ENABLED (JERRY_ES2015_FOR_OF)
|| context_p->stack_top_uint8 == PARSER_STATEMENT_FOR_OF
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
|| context_p->stack_top_uint8 == PARSER_STATEMENT_WITH)
{
parser_raise_error (context_p, PARSER_ERR_STATEMENT_EXPECTED);
@@ -2619,6 +2783,34 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
parser_set_branch_to_current_position (context_p, &for_in_statement.branch);
continue;
}
#if ENABLED (JERRY_ES2015_FOR_OF)
case PARSER_STATEMENT_FOR_OF:
{
parser_for_of_statement_t for_of_statement;
parser_loop_statement_t loop;
parser_stack_pop_uint8 (context_p);
parser_stack_pop (context_p, &loop, sizeof (parser_loop_statement_t));
parser_stack_pop (context_p, &for_of_statement, sizeof (parser_for_of_statement_t));
parser_stack_iterator_init (context_p, &context_p->last_statement);
parser_set_continues_to_current_position (context_p, loop.branch_list_p);
parser_flush_cbc (context_p);
PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION);
#ifndef JERRY_NDEBUG
PARSER_MINUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_FOR_OF_CONTEXT_STACK_ALLOCATION);
#endif /* !JERRY_NDEBUG */
parser_emit_cbc_ext_backward_branch (context_p,
CBC_EXT_BRANCH_IF_FOR_OF_HAS_NEXT,
for_of_statement.start_offset);
parser_set_breaks_to_current_position (context_p, loop.branch_list_p);
parser_set_branch_to_current_position (context_p, &for_of_statement.branch);
continue;
}
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
case PARSER_STATEMENT_WITH:
{
@@ -2705,6 +2897,9 @@ parser_free_jumps (parser_stack_iterator_t iterator) /**< iterator position */
case PARSER_STATEMENT_WHILE:
case PARSER_STATEMENT_FOR:
case PARSER_STATEMENT_FOR_IN:
#if ENABLED (JERRY_ES2015_FOR_OF)
case PARSER_STATEMENT_FOR_OF:
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
{
parser_loop_statement_t loop;
+6
View File
@@ -954,6 +954,12 @@ parser_error_to_string (parser_error_t error) /**< error code */
{
return "Expected 'in' token.";
}
#if ENABLED (JERRY_ES2015_FOR_OF)
case PARSER_ERR_OF_EXPECTED:
{
return "Expected 'of' token.";
}
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
case PARSER_ERR_WHILE_EXPECTED:
{
return "While expected for do-while loop.";
+3
View File
@@ -98,6 +98,9 @@ typedef enum
PARSER_ERR_COLON_FOR_CONDITIONAL_EXPECTED, /**< colon expected for conditional expression */
PARSER_ERR_SEMICOLON_EXPECTED, /**< semicolon expected */
PARSER_ERR_IN_EXPECTED, /**< in keyword expected */
#if ENABLED (JERRY_ES2015_FOR_OF)
PARSER_ERR_OF_EXPECTED, /**< of keyword expected */
#endif /* ENABLED (JERRY_ES2015_FOR_OF) */
PARSER_ERR_WHILE_EXPECTED, /**< while expected for do-while loop */
PARSER_ERR_CATCH_FINALLY_EXPECTED, /**< catch or finally expected */
PARSER_ERR_ARRAY_ITEM_SEPARATOR_EXPECTED, /**< array item separator expected */