Patch 8.2.1067

4 views
Skip to first unread message

Bram Moolenaar

unread,
Jun 27, 2020, 7:12:26 AM6/27/20
to vim...@googlegroups.com

Patch 8.2.1067
Problem: Expression "!expr->func()" does not work.
Solution: Apply plus and minus earlier. (closes #6348)
Files: src/eval.c, src/proto/eval.pro, src/evalvars.c, src/userfunc.c,
src/testdir/test_expr.vim, src/testdir/test_vim9_expr.vim


*** ../vim-8.2.1066/src/eval.c 2020-06-26 22:46:23.229370947 +0200
--- src/eval.c 2020-06-27 12:55:24.069015504 +0200
***************
*** 51,57 ****
static int eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
static int eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
static int eval7(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
! static int eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp);

static int free_unref_items(int copyID);
static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end);
--- 51,57 ----
static int eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
static int eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
static int eval7(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
! static int eval7_leader(typval_T *rettv, int numeric_only, char_u *start_leader, char_u **end_leaderp);

static int free_unref_items(int copyID);
static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end);
***************
*** 2756,2761 ****
--- 2756,2766 ----
case '8':
case '9':
case '.': ret = get_number_tv(arg, rettv, evaluate, want_string);
+
+ // Apply prefixed "-" and "+" now. Matters especially when
+ // "->" follows.
+ if (ret == OK && evaluate && end_leader > start_leader)
+ ret = eval7_leader(rettv, TRUE, start_leader, &end_leader);
break;

/*
***************
*** 2879,2901 ****
// Handle following '[', '(' and '.' for expr[expr], expr.name,
// expr(expr), expr->name(expr)
if (ret == OK)
! ret = handle_subscript(arg, rettv, flags, TRUE,
! start_leader, &end_leader);

/*
* Apply logical NOT and unary '-', from right to left, ignore '+'.
*/
if (ret == OK && evaluate && end_leader > start_leader)
! ret = eval7_leader(rettv, start_leader, &end_leader);
return ret;
}

/*
* Apply the leading "!" and "-" before an eval7 expression to "rettv".
* Adjusts "end_leaderp" until it is at "start_leader".
*/
static int
! eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp)
{
char_u *end_leader = *end_leaderp;
int ret = OK;
--- 2884,2910 ----
// Handle following '[', '(' and '.' for expr[expr], expr.name,
// expr(expr), expr->name(expr)
if (ret == OK)
! ret = handle_subscript(arg, rettv, flags, TRUE);

/*
* Apply logical NOT and unary '-', from right to left, ignore '+'.
*/
if (ret == OK && evaluate && end_leader > start_leader)
! ret = eval7_leader(rettv, FALSE, start_leader, &end_leader);
return ret;
}

/*
* Apply the leading "!" and "-" before an eval7 expression to "rettv".
+ * When "numeric_only" is TRUE only handle "+" and "-".
* Adjusts "end_leaderp" until it is at "start_leader".
*/
static int
! eval7_leader(
! typval_T *rettv,
! int numeric_only,
! char_u *start_leader,
! char_u **end_leaderp)
{
char_u *end_leader = *end_leaderp;
int ret = OK;
***************
*** 2921,2926 ****
--- 2930,2940 ----
--end_leader;
if (*end_leader == '!')
{
+ if (numeric_only)
+ {
+ ++end_leader;
+ break;
+ }
#ifdef FEAT_FLOAT
if (rettv->v_type == VAR_FLOAT)
f = !f;
***************
*** 4871,4879 ****
char_u **arg,
typval_T *rettv,
int flags, // do more than finding the end
! int verbose, // give error messages
! char_u *start_leader, // start of '!' and '-' prefixes
! char_u **end_leaderp) // end of '!' and '-' prefixes
{
int evaluate = flags & EVAL_EVALUATE;
int ret = OK;
--- 4885,4891 ----
char_u **arg,
typval_T *rettv,
int flags, // do more than finding the end
! int verbose) // give error messages
{
int evaluate = flags & EVAL_EVALUATE;
int ret = OK;
***************
*** 4910,4919 ****
}
else if (**arg == '-')
{
- // Expression "-1.0->method()" applies the leader "-" before
- // applying ->.
- if (evaluate && *end_leaderp > start_leader)
- ret = eval7_leader(rettv, start_leader, end_leaderp);
if (ret == OK)
{
if ((*arg)[2] == '{')
--- 4922,4927 ----
*** ../vim-8.2.1066/src/proto/eval.pro 2020-06-26 22:46:23.233370940 +0200
--- src/proto/eval.pro 2020-06-27 12:57:32.324317482 +0200
***************
*** 53,59 ****
char_u *find_name_end(char_u *arg, char_u **expr_start, char_u **expr_end, int flags);
int eval_isnamec(int c);
int eval_isnamec1(int c);
! int handle_subscript(char_u **arg, typval_T *rettv, int flags, int verbose, char_u *start_leader, char_u **end_leaderp);
int item_copy(typval_T *from, typval_T *to, int deep, int copyID);
void echo_one(typval_T *rettv, int with_space, int *atstart, int *needclr);
void ex_echo(exarg_T *eap);
--- 53,59 ----
char_u *find_name_end(char_u *arg, char_u **expr_start, char_u **expr_end, int flags);
int eval_isnamec(int c);
int eval_isnamec1(int c);
! int handle_subscript(char_u **arg, typval_T *rettv, int flags, int verbose);
int item_copy(typval_T *from, typval_T *to, int deep, int copyID);
void echo_one(typval_T *rettv, int with_space, int *atstart, int *needclr);
void ex_echo(exarg_T *eap);
*** ../vim-8.2.1066/src/evalvars.c 2020-06-24 20:33:59.565106319 +0200
--- src/evalvars.c 2020-06-27 12:57:09.224406396 +0200
***************
*** 1125,1132 ****
{
// handle d.key, l[idx], f(expr)
arg_subsc = arg;
! if (handle_subscript(&arg, &tv, EVAL_EVALUATE, TRUE,
! name, &name) == FAIL)
error = TRUE;
else
{
--- 1125,1132 ----
{
// handle d.key, l[idx], f(expr)
arg_subsc = arg;
! if (handle_subscript(&arg, &tv, EVAL_EVALUATE, TRUE)
! == FAIL)
error = TRUE;
else
{
***************
*** 3341,3348 ****
if (n)
{
// handle d.key, l[idx], f(expr)
! n = (handle_subscript(&var, &tv, EVAL_EVALUATE,
! FALSE, name, &name) == OK);
if (n)
clear_tv(&tv);
}
--- 3341,3347 ----
if (n)
{
// handle d.key, l[idx], f(expr)
! n = (handle_subscript(&var, &tv, EVAL_EVALUATE, FALSE) == OK);
if (n)
clear_tv(&tv);
}
*** ../vim-8.2.1066/src/userfunc.c 2020-06-25 19:27:53.036387595 +0200
--- src/userfunc.c 2020-06-27 12:57:16.540376614 +0200
***************
*** 3926,3932 ****

// Handle a function returning a Funcref, Dictionary or List.
if (handle_subscript(&arg, &rettv, eap->skip ? 0 : EVAL_EVALUATE,
! TRUE, name, &name) == FAIL)
{
failed = TRUE;
break;
--- 3926,3932 ----

// Handle a function returning a Funcref, Dictionary or List.
if (handle_subscript(&arg, &rettv, eap->skip ? 0 : EVAL_EVALUATE,
! TRUE) == FAIL)
{
failed = TRUE;
break;
*** ../vim-8.2.1066/src/testdir/test_expr.vim 2020-04-26 15:59:51.202952140 +0200
--- src/testdir/test_expr.vim 2020-06-27 13:06:47.393393602 +0200
***************
*** 110,115 ****
--- 110,122 ----
call assert_fails('echo "\<C-">')
endfunc

+ func Test_method_with_prefix()
+ call assert_equal(1, !range(5)->empty())
+ call assert_equal([0, 1, 2], --3->range())
+ call assert_equal(0, !-3)
+ call assert_equal(1, !+-+0)
+ endfunc
+
func Test_option_value()
" boolean
set bri
*** ../vim-8.2.1066/src/testdir/test_vim9_expr.vim 2020-06-26 22:46:23.233370940 +0200
--- src/testdir/test_vim9_expr.vim 2020-06-27 13:09:21.730382191 +0200
***************
*** 1081,1086 ****
--- 1081,1088 ----
assert_equal(6, --6)
assert_equal(6, -+-6)
assert_equal(-6, ---6)
+ assert_equal(false, !-3)
+ assert_equal(true, !+-+0)
enddef

def Test_expr7_negate()
***************
*** 1102,1107 ****
--- 1104,1111 ----
def Test_expr7_call()
assert_equal('yes', 'yes'->Echo())
assert_equal('yes', 'yes'->s:EchoArg())
+ assert_equal(1, !range(5)->empty())
+ assert_equal([0, 1, 2], --3->range())

call CheckDefFailure(["let x = 'yes'->Echo"], 'E107:')
enddef
*** ../vim-8.2.1066/src/version.c 2020-06-27 12:32:54.315608887 +0200
--- src/version.c 2020-06-27 13:10:01.210663462 +0200
***************
*** 756,757 ****
--- 756,759 ----
{ /* Add new patch number below this line */
+ /**/
+ 1067,
/**/

--
If you only have a hammer, you tend to see every problem as a nail.
If you only have MS-Windows, you tend to solve every problem by rebooting.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages