eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
{
    /*
     * Get the first expression.
     */
    if (eval6(arg, rettv, evalarg) == FAIL)
	return FAIL;

    /*
     * Repeat computing, until no '<<' or '>>' is following.
     */
    for (;;)
    {
	char_u		*p;
	int		getnext;
	exprtype_T	type;
	int		evaluate;
	typval_T	var2;
	int		vim9script;

	p = eval_next_non_blank(*arg, evalarg, &getnext);
	if (p[0] == '<' && p[1] == '<')
	    type = EXPR_LSHIFT;
	else if (p[0] == '>' && p[1] == '>')
	    type = EXPR_RSHIFT;
	else
	    return OK;

	// Handle a bitwise left or right shift operator
	if (rettv->v_type != VAR_NUMBER)
	{
	    // left operand should be a number
	    emsg(_(e_bitshift_ops_must_be_number));
	    clear_tv(rettv);
	    return FAIL;
	}

	evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
	vim9script = in_vim9script();
	if (getnext)
	{
	    *arg = eval_next_line(*arg, evalarg);
	    p = *arg;
	}
	else if (evaluate && vim9script && !VIM_ISWHITE(**arg))
	{
	    error_white_both(*arg, 2);
	    clear_tv(rettv);
	    return FAIL;
	}

	/*
	 * Get the second variable.
	 */
	if (evaluate && vim9script && !IS_WHITE_OR_NUL(p[2]))
	{
	    error_white_both(p, 2);
	    clear_tv(rettv);
	    return FAIL;
	}
	*arg = skipwhite_and_linebreak(p + 2, evalarg);
	if (eval6(arg, &var2, evalarg) == FAIL)
	{
	    clear_tv(rettv);
	    return FAIL;
	}

	if (var2.v_type != VAR_NUMBER || var2.vval.v_number < 0)
	{
	    // right operand should be a positive number
	    if (var2.v_type != VAR_NUMBER)
		emsg(_(e_bitshift_ops_must_be_number));
	    else
		emsg(_(e_bitshift_ops_must_be_postive));
	    clear_tv(rettv);
	    clear_tv(&var2);
	    return FAIL;
	}

	if (evaluate)
	{
	    if (var2.vval.v_number > MAX_LSHIFT_BITS)
		// shifting more bits than we have always results in zero
		rettv->vval.v_number = 0;
	    else if (type == EXPR_LSHIFT)
		rettv->vval.v_number =
		      (uvarnumber_T)rettv->vval.v_number << var2.vval.v_number;
	    else
		rettv->vval.v_number =
		      (uvarnumber_T)rettv->vval.v_number >> var2.vval.v_number;
	}

	clear_tv(&var2);
    }

    return OK;
}
eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
{
     
    if (eval6(arg, rettv, evalarg) == FAIL)
	return FAIL;

     
    for (;;)
    {
	char_u		*p;
	int		getnext;
	exprtype_T	type;
	int		evaluate;
	typval_T	var2;
	int		vim9script;

	p = eval_next_non_blank(*arg, evalarg, &getnext);
	if (p[0] == '<' && p[1] == '<')
	    type = EXPR_LSHIFT;
	else if (p[0] == '>' && p[1] == '>')
	    type = EXPR_RSHIFT;
	else
	    return OK;

	 
	if (rettv->v_type != VAR_NUMBER)
	{
	     
	    emsg(_(e_bitshift_ops_must_be_number));
	    clear_tv(rettv);
	    return FAIL;
	}

	evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
	vim9script = in_vim9script();
	if (getnext)
	{
	    *arg = eval_next_line(*arg, evalarg);
	    p = *arg;
	}
	else if (evaluate && vim9script && !VIM_ISWHITE(**arg))
	{
	    error_white_both(*arg, 2);
	    clear_tv(rettv);
	    return FAIL;
	}

	 
	if (evaluate && vim9script && !IS_WHITE_OR_NUL(p[2]))
	{
	    error_white_both(p, 2);
	    clear_tv(rettv);
	    return FAIL;
	}
	*arg = skipwhite_and_linebreak(p + 2, evalarg);
	if (eval6(arg, &var2, evalarg) == FAIL)
	{
	    clear_tv(rettv);
	    return FAIL;
	}

	if (var2.v_type != VAR_NUMBER || var2.vval.v_number < 0)
	{
	     
	    if (var2.v_type != VAR_NUMBER)
		emsg(_(e_bitshift_ops_must_be_number));
	    else
		emsg(_(e_bitshift_ops_must_be_postive));
	    clear_tv(rettv);
	    clear_tv(&var2);
	    return FAIL;
	}

	if (evaluate)
	{
	    if (var2.vval.v_number > MAX_LSHIFT_BITS)
		 
		rettv->vval.v_number = 0;
	    else if (type == EXPR_LSHIFT)
		rettv->vval.v_number =
		      (uvarnumber_T)rettv->vval.v_number << var2.vval.v_number;
	    else
		rettv->vval.v_number =
		      (uvarnumber_T)rettv->vval.v_number >> var2.vval.v_number;
	}

	clear_tv(&var2);
    }

    return OK;
}