parser_parse_tagged_template_literal (parser_context_t *context_p) /**< context */
{
  JERRY_ASSERT (context_p->token.type == LEXER_TEMPLATE_LITERAL);

  uint32_t call_arguments = 0;
  ecma_collection_t *collection_p;

  if (context_p->tagged_template_literal_cp == JMEM_CP_NULL)
  {
    collection_p = ecma_new_collection ();
    ECMA_SET_INTERNAL_VALUE_POINTER (context_p->tagged_template_literal_cp, collection_p);
  }
  else
  {
    collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, context_p->tagged_template_literal_cp);
    if (collection_p->item_count > CBC_MAXIMUM_BYTE_VALUE)
    {
      parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED);
    }
  }

  const uint32_t tagged_id = collection_p->item_count;
  uint32_t prop_idx = 0;
  ecma_object_t *raw_strings_p;
  ecma_object_t *template_obj_p = parser_new_tagged_template_literal (&raw_strings_p);
  ecma_collection_push_back (collection_p, ecma_make_object_value (template_obj_p));

  parser_tagged_template_literal_append_strings (context_p, template_obj_p, raw_strings_p, prop_idx++);

  call_arguments++;
  parser_emit_cbc_ext_call (context_p, CBC_EXT_GET_TAGGED_TEMPLATE_LITERAL, tagged_id);

  while (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT)
  {
    JERRY_ASSERT (context_p->source_p[-1] == LIT_CHAR_LEFT_BRACE);
    lexer_next_token (context_p);

    if (++call_arguments > CBC_MAXIMUM_BYTE_VALUE)
    {
      parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED);
    }

    parser_parse_expression (context_p, PARSE_EXPR);

    if (context_p->token.type != LEXER_RIGHT_BRACE)
    {
      parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED);
    }

    context_p->source_p--;
    context_p->column--;
    lexer_parse_string (context_p, LEXER_STRING_NO_OPTS);

    parser_tagged_template_literal_append_strings (context_p, template_obj_p, raw_strings_p, prop_idx++);
  }

  parser_tagged_template_literal_finalize (template_obj_p, raw_strings_p);

  return call_arguments;
} /* parser_parse_tagged_template_literal */
parser_parse_tagged_template_literal (parser_context_t *context_p)  
{
  JERRY_ASSERT (context_p->token.type == LEXER_TEMPLATE_LITERAL);

  uint32_t call_arguments = 0;
  ecma_collection_t *collection_p;

  if (context_p->tagged_template_literal_cp == JMEM_CP_NULL)
  {
    collection_p = ecma_new_collection ();
    ECMA_SET_INTERNAL_VALUE_POINTER (context_p->tagged_template_literal_cp, collection_p);
  }
  else
  {
    collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, context_p->tagged_template_literal_cp);
    if (collection_p->item_count > CBC_MAXIMUM_BYTE_VALUE)
    {
      parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED);
    }
  }

  const uint32_t tagged_id = collection_p->item_count;
  uint32_t prop_idx = 0;
  ecma_object_t *raw_strings_p;
  ecma_object_t *template_obj_p = parser_new_tagged_template_literal (&raw_strings_p);
  ecma_collection_push_back (collection_p, ecma_make_object_value (template_obj_p));

  parser_tagged_template_literal_append_strings (context_p, template_obj_p, raw_strings_p, prop_idx++);

  call_arguments++;
  parser_emit_cbc_ext_call (context_p, CBC_EXT_GET_TAGGED_TEMPLATE_LITERAL, tagged_id);

  while (context_p->source_p[-1] != LIT_CHAR_GRAVE_ACCENT)
  {
    JERRY_ASSERT (context_p->source_p[-1] == LIT_CHAR_LEFT_BRACE);
    lexer_next_token (context_p);

    if (++call_arguments > CBC_MAXIMUM_BYTE_VALUE)
    {
      parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIMIT_REACHED);
    }

    parser_parse_expression (context_p, PARSE_EXPR);

    if (context_p->token.type != LEXER_RIGHT_BRACE)
    {
      parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED);
    }

    context_p->source_p--;
    context_p->column--;
    lexer_parse_string (context_p, LEXER_STRING_NO_OPTS);

    parser_tagged_template_literal_append_strings (context_p, template_obj_p, raw_strings_p, prop_idx++);
  }

  parser_tagged_template_literal_finalize (template_obj_p, raw_strings_p);

  return call_arguments;
}  