parser_parse_arrow_function (parser_context_t *context_p, /**< context */
                             uint32_t status_flags) /**< extra status flags */
{
  parser_saved_context_t saved_context;
  ecma_compiled_code_t *compiled_code_p;

  JERRY_ASSERT (status_flags & PARSER_IS_FUNCTION);
  JERRY_ASSERT (status_flags & PARSER_IS_ARROW_FUNCTION);
  parser_save_context (context_p, &saved_context);
  context_p->status_flags |= status_flags;
  context_p->status_flags |= saved_context.status_flags & (PARSER_ALLOW_NEW_TARGET
                                                           | PARSER_ALLOW_SUPER
                                                           | PARSER_ALLOW_SUPER_CALL);

#if JERRY_PARSER_DUMP_BYTE_CODE
  if (context_p->is_show_opcodes)
  {
    JERRY_DEBUG_MSG ("\n--- Arrow function parsing start ---\n\n");
  }
#endif /* JERRY_PARSER_DUMP_BYTE_CODE */

#if JERRY_DEBUGGER
  if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
  {
    jerry_debugger_send_parse_function (context_p->token.line, context_p->token.column);
  }
#endif /* JERRY_DEBUGGER */

  if (context_p->token.type == LEXER_LEFT_PAREN)
  {
    lexer_next_token (context_p);
    parser_parse_function_arguments (context_p, LEXER_RIGHT_PAREN);
    lexer_next_token (context_p);
  }
  else
  {
    parser_parse_function_arguments (context_p, LEXER_ARROW);
  }

  JERRY_ASSERT (context_p->token.type == LEXER_ARROW);

  lexer_next_token (context_p);

  if (context_p->token.type == LEXER_LEFT_BRACE)
  {
    lexer_next_token (context_p);

    context_p->status_flags |= PARSER_IS_CLOSURE;
    parser_parse_statements (context_p);

    /* Unlike normal function, arrow functions consume their close brace. */
    JERRY_ASSERT (context_p->token.type == LEXER_RIGHT_BRACE);
    lexer_next_token (context_p);
  }
  else
  {
    if (context_p->status_flags & PARSER_IS_STRICT
        && context_p->status_flags & PARSER_HAS_NON_STRICT_ARG)
    {
      parser_raise_error (context_p, PARSER_ERR_NON_STRICT_ARG_DEFINITION);
    }

#if JERRY_LINE_INFO
    parser_line_info_append (context_p, context_p->token.line, context_p->token.column);
#endif /* JERRY_LINE_INFO */

    parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);

    if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
    {
      context_p->last_cbc_opcode = CBC_RETURN_WITH_LITERAL;
    }
    else
    {
      parser_emit_cbc (context_p, CBC_RETURN);
    }
    parser_flush_cbc (context_p);

    lexer_update_await_yield (context_p, saved_context.status_flags);
  }

  compiled_code_p = parser_post_processing (context_p);

#if JERRY_PARSER_DUMP_BYTE_CODE
  if (context_p->is_show_opcodes)
  {
    JERRY_DEBUG_MSG ("\n--- Arrow function parsing end ---\n\n");
  }
#endif /* JERRY_PARSER_DUMP_BYTE_CODE */

  parser_restore_context (context_p, &saved_context);

  return compiled_code_p;
} /* parser_parse_arrow_function */
parser_parse_arrow_function (parser_context_t *context_p,  
                             uint32_t status_flags)  
{
  parser_saved_context_t saved_context;
  ecma_compiled_code_t *compiled_code_p;

  JERRY_ASSERT (status_flags & PARSER_IS_FUNCTION);
  JERRY_ASSERT (status_flags & PARSER_IS_ARROW_FUNCTION);
  parser_save_context (context_p, &saved_context);
  context_p->status_flags |= status_flags;
  context_p->status_flags |= saved_context.status_flags & (PARSER_ALLOW_NEW_TARGET
                                                           | PARSER_ALLOW_SUPER
                                                           | PARSER_ALLOW_SUPER_CALL);

#if JERRY_PARSER_DUMP_BYTE_CODE
  if (context_p->is_show_opcodes)
  {
    JERRY_DEBUG_MSG ("\n--- Arrow function parsing start ---\n\n");
  }
#endif  

#if JERRY_DEBUGGER
  if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
  {
    jerry_debugger_send_parse_function (context_p->token.line, context_p->token.column);
  }
#endif  

  if (context_p->token.type == LEXER_LEFT_PAREN)
  {
    lexer_next_token (context_p);
    parser_parse_function_arguments (context_p, LEXER_RIGHT_PAREN);
    lexer_next_token (context_p);
  }
  else
  {
    parser_parse_function_arguments (context_p, LEXER_ARROW);
  }

  JERRY_ASSERT (context_p->token.type == LEXER_ARROW);

  lexer_next_token (context_p);

  if (context_p->token.type == LEXER_LEFT_BRACE)
  {
    lexer_next_token (context_p);

    context_p->status_flags |= PARSER_IS_CLOSURE;
    parser_parse_statements (context_p);

     
    JERRY_ASSERT (context_p->token.type == LEXER_RIGHT_BRACE);
    lexer_next_token (context_p);
  }
  else
  {
    if (context_p->status_flags & PARSER_IS_STRICT
        && context_p->status_flags & PARSER_HAS_NON_STRICT_ARG)
    {
      parser_raise_error (context_p, PARSER_ERR_NON_STRICT_ARG_DEFINITION);
    }

#if JERRY_LINE_INFO
    parser_line_info_append (context_p, context_p->token.line, context_p->token.column);
#endif  

    parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);

    if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
    {
      context_p->last_cbc_opcode = CBC_RETURN_WITH_LITERAL;
    }
    else
    {
      parser_emit_cbc (context_p, CBC_RETURN);
    }
    parser_flush_cbc (context_p);

    lexer_update_await_yield (context_p, saved_context.status_flags);
  }

  compiled_code_p = parser_post_processing (context_p);

#if JERRY_PARSER_DUMP_BYTE_CODE
  if (context_p->is_show_opcodes)
  {
    JERRY_DEBUG_MSG ("\n--- Arrow function parsing end ---\n\n");
  }
#endif  

  parser_restore_context (context_p, &saved_context);

  return compiled_code_p;
}  