parser_append_binary_single_assignment_token (parser_context_t *context_p, /**< context */
                                              uint32_t pattern_flags) /**< pattern flags */
{
  JERRY_UNUSED (pattern_flags);

  /* Unlike other tokens, the whole byte code is saved for binary
   * assignment, since it has multiple forms depending on the
   * previous instruction. */

  uint8_t assign_opcode = CBC_ASSIGN;

  if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
      && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
  {
    parser_check_invalid_assign (context_p);

    uint16_t literal_index;

    switch (context_p->last_cbc_opcode)
    {
      case CBC_PUSH_LITERAL:
      {
        literal_index = context_p->last_cbc.literal_index;
        context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
        break;
      }
      case CBC_PUSH_TWO_LITERALS:
      {
        literal_index = context_p->last_cbc.value;
        context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
        break;
      }
      case CBC_PUSH_THIS_LITERAL:
      {
        literal_index = context_p->last_cbc.literal_index;
        context_p->last_cbc_opcode = CBC_PUSH_THIS;
        parser_flush_cbc (context_p);
        break;
      }
      default:
      {
        JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS);
        literal_index = context_p->last_cbc.third_literal_index;
        context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
        break;
      }
    }

    assign_opcode = CBC_ASSIGN_SET_IDENT;

#if JERRY_ESNEXT
    if (!(pattern_flags & (PARSER_PATTERN_LET | PARSER_PATTERN_CONST | PARSER_PATTERN_LOCAL)))
    {
      if (scanner_literal_is_const_reg (context_p, literal_index))
      {
        parser_stack_push_uint8 (context_p, LEXER_ASSIGN_CONST);
      }
    }
    else if (literal_index < PARSER_REGISTER_START)
    {
      assign_opcode = CBC_INIT_LET;

      if (scanner_literal_is_created (context_p, literal_index))
      {
        assign_opcode = CBC_ASSIGN_LET_CONST;
      }
      else if (pattern_flags & PARSER_PATTERN_CONST)
      {
        assign_opcode = CBC_INIT_CONST;
      }
      else if (pattern_flags & PARSER_PATTERN_LOCAL)
      {
        assign_opcode = CBC_INIT_ARG_OR_CATCH;
      }
    }
#endif /* JERRY_ESNEXT */

    parser_stack_push_uint16 (context_p, literal_index);
    JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, assign_opcode));
  }
  else if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
  {
    JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP, CBC_ASSIGN));
    context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
  }
  else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL)
  {
    if (context_p->last_cbc.literal_type != LEXER_IDENT_LITERAL)
    {
      JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL, CBC_ASSIGN_PROP_LITERAL));
      parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index);
      assign_opcode = CBC_ASSIGN_PROP_LITERAL;
      context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
    }
    else
    {
      context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
    }
  }
  else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL_LITERAL)
  {
    JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL_LITERAL, CBC_PUSH_TWO_LITERALS));
    context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
  }
  else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_THIS_LITERAL)
  {
    if (context_p->last_cbc.literal_type != LEXER_IDENT_LITERAL)
    {
      JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_THIS_LITERAL, CBC_ASSIGN_PROP_THIS_LITERAL));
      parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index);
      assign_opcode = CBC_ASSIGN_PROP_THIS_LITERAL;
      context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
    }
    else
    {
      context_p->last_cbc_opcode = CBC_PUSH_THIS_LITERAL;
    }
  }
#if JERRY_ESNEXT
  else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL))
  {
    context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_ASSIGNMENT_REFERENCE);
    parser_stack_push_uint8 (context_p, CBC_EXT_ASSIGN_SUPER);
    assign_opcode = CBC_EXT_OPCODE;
  }
  else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP))
  {
    context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE);
    parser_stack_push_uint8 (context_p, CBC_EXT_ASSIGN_SUPER);
    assign_opcode = CBC_EXT_OPCODE;
  }
#endif /* JERRY_ESNEXT */
  else
  {
    /* Invalid LeftHandSide expression. */ //3820, 3815
#if JERRY_ESNEXT
    parser_check_invalid_new_target (context_p, CBC_ASSIGN);
    parser_raise_error (context_p, PARSER_ERR_INVALID_LHS_ASSIGNMENT);
#else /* !JERRY_ESNEXT */
    parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
#endif /* JERRY_ESNEXT */
  }

  parser_stack_push_uint8 (context_p, assign_opcode);
  parser_stack_push_uint8 (context_p, LEXER_ASSIGN);
} /* parser_append_binary_single_assignment_token */
parser_append_binary_single_assignment_token (parser_context_t *context_p,  
                                              uint32_t pattern_flags)  
{
  JERRY_UNUSED (pattern_flags);

   

  uint8_t assign_opcode = CBC_ASSIGN;

  if (PARSER_IS_PUSH_LITERALS_WITH_THIS (context_p->last_cbc_opcode)
      && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
  {
    parser_check_invalid_assign (context_p);

    uint16_t literal_index;

    switch (context_p->last_cbc_opcode)
    {
      case CBC_PUSH_LITERAL:
      {
        literal_index = context_p->last_cbc.literal_index;
        context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
        break;
      }
      case CBC_PUSH_TWO_LITERALS:
      {
        literal_index = context_p->last_cbc.value;
        context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
        break;
      }
      case CBC_PUSH_THIS_LITERAL:
      {
        literal_index = context_p->last_cbc.literal_index;
        context_p->last_cbc_opcode = CBC_PUSH_THIS;
        parser_flush_cbc (context_p);
        break;
      }
      default:
      {
        JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS);
        literal_index = context_p->last_cbc.third_literal_index;
        context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
        break;
      }
    }

    assign_opcode = CBC_ASSIGN_SET_IDENT;

#if JERRY_ESNEXT
    if (!(pattern_flags & (PARSER_PATTERN_LET | PARSER_PATTERN_CONST | PARSER_PATTERN_LOCAL)))
    {
      if (scanner_literal_is_const_reg (context_p, literal_index))
      {
        parser_stack_push_uint8 (context_p, LEXER_ASSIGN_CONST);
      }
    }
    else if (literal_index < PARSER_REGISTER_START)
    {
      assign_opcode = CBC_INIT_LET;

      if (scanner_literal_is_created (context_p, literal_index))
      {
        assign_opcode = CBC_ASSIGN_LET_CONST;
      }
      else if (pattern_flags & PARSER_PATTERN_CONST)
      {
        assign_opcode = CBC_INIT_CONST;
      }
      else if (pattern_flags & PARSER_PATTERN_LOCAL)
      {
        assign_opcode = CBC_INIT_ARG_OR_CATCH;
      }
    }
#endif  

    parser_stack_push_uint16 (context_p, literal_index);
    JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_LITERAL, assign_opcode));
  }
  else if (context_p->last_cbc_opcode == CBC_PUSH_PROP)
  {
    JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP, CBC_ASSIGN));
    context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
  }
  else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL)
  {
    if (context_p->last_cbc.literal_type != LEXER_IDENT_LITERAL)
    {
      JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL, CBC_ASSIGN_PROP_LITERAL));
      parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index);
      assign_opcode = CBC_ASSIGN_PROP_LITERAL;
      context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
    }
    else
    {
      context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
    }
  }
  else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_LITERAL_LITERAL)
  {
    JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_LITERAL_LITERAL, CBC_PUSH_TWO_LITERALS));
    context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
  }
  else if (context_p->last_cbc_opcode == CBC_PUSH_PROP_THIS_LITERAL)
  {
    if (context_p->last_cbc.literal_type != LEXER_IDENT_LITERAL)
    {
      JERRY_ASSERT (CBC_SAME_ARGS (CBC_PUSH_PROP_THIS_LITERAL, CBC_ASSIGN_PROP_THIS_LITERAL));
      parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index);
      assign_opcode = CBC_ASSIGN_PROP_THIS_LITERAL;
      context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
    }
    else
    {
      context_p->last_cbc_opcode = CBC_PUSH_THIS_LITERAL;
    }
  }
#if JERRY_ESNEXT
  else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL))
  {
    context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_ASSIGNMENT_REFERENCE);
    parser_stack_push_uint8 (context_p, CBC_EXT_ASSIGN_SUPER);
    assign_opcode = CBC_EXT_OPCODE;
  }
  else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP))
  {
    context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE);
    parser_stack_push_uint8 (context_p, CBC_EXT_ASSIGN_SUPER);
    assign_opcode = CBC_EXT_OPCODE;
  }
#endif  
  else
  {
       
#if JERRY_ESNEXT
    parser_check_invalid_new_target (context_p, CBC_ASSIGN);
    parser_raise_error (context_p, PARSER_ERR_INVALID_LHS_ASSIGNMENT);
#else  
    parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
#endif  
  }

  parser_stack_push_uint8 (context_p, assign_opcode);
  parser_stack_push_uint8 (context_p, LEXER_ASSIGN);
}  