Skip to content

Commit 59eccb9

Browse files
committed
patch 8.2.1419: Vim9: not operator applied too early
Problem: Vim9: not operator applied too early. Solution: Implement the "numeric_only" argument. (closes #6680)
1 parent 8294d49 commit 59eccb9

3 files changed

Lines changed: 35 additions & 16 deletions

File tree

src/testdir/test_vim9_expr.vim

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1744,7 +1744,7 @@ def Test_expr7_call()
17441744
assert_equal('yes', 'yes'->Echo())
17451745
assert_equal('yes', 'yes'
17461746
->s:Echo4Arg())
1747-
assert_equal(1, !range(5)->empty())
1747+
assert_equal(true, !range(5)->empty())
17481748
assert_equal([0, 1, 2], --3->range())
17491749

17501750
call CheckDefFailure(["let x = 'yes'->Echo"], 'E107:')
@@ -1782,6 +1782,9 @@ def Test_expr7_not()
17821782

17831783
assert_equal(true, !test_void())
17841784
assert_equal(true, !test_unknown())
1785+
1786+
assert_equal(false, ![1, 2, 3]->reverse())
1787+
assert_equal(true, ![]->reverse())
17851788
END
17861789
CheckDefSuccess(lines)
17871790
CheckScriptSuccess(['vim9script'] + lines)

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,8 @@ static char *(features[]) =
754754

755755
static int included_patches[] =
756756
{ /* Add new patch number below this line */
757+
/**/
758+
1419,
757759
/**/
758760
1418,
759761
/**/

src/vim9compile.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2723,11 +2723,12 @@ compile_get_register(char_u **arg, cctx_T *cctx)
27232723

27242724
/*
27252725
* Apply leading '!', '-' and '+' to constant "rettv".
2726+
* When "numeric_only" is TRUE do not apply '!'.
27262727
*/
27272728
static int
2728-
apply_leader(typval_T *rettv, char_u *start, char_u *end)
2729+
apply_leader(typval_T *rettv, int numeric_only, char_u *start, char_u **end)
27292730
{
2730-
char_u *p = end;
2731+
char_u *p = *end;
27312732

27322733
// this works from end to start
27332734
while (p > start)
@@ -2762,6 +2763,11 @@ apply_leader(typval_T *rettv, char_u *start, char_u *end)
27622763
rettv->vval.v_number = val;
27632764
}
27642765
}
2766+
else if (numeric_only)
2767+
{
2768+
++p;
2769+
break;
2770+
}
27652771
else
27662772
{
27672773
int v = tv2bool(rettv);
@@ -2772,6 +2778,7 @@ apply_leader(typval_T *rettv, char_u *start, char_u *end)
27722778
rettv->vval.v_number = v ? VVAL_FALSE : VVAL_TRUE;
27732779
}
27742780
}
2781+
*end = p;
27752782
return OK;
27762783
}
27772784

@@ -2860,11 +2867,12 @@ get_compare_type(char_u *p, int *len, int *type_is)
28602867

28612868
/*
28622869
* Compile code to apply '-', '+' and '!'.
2870+
* When "numeric_only" is TRUE do not apply '!'.
28632871
*/
28642872
static int
2865-
compile_leader(cctx_T *cctx, char_u *start, char_u *end)
2873+
compile_leader(cctx_T *cctx, int numeric_only, char_u *start, char_u **end)
28662874
{
2867-
char_u *p = end;
2875+
char_u *p = *end;
28682876

28692877
// this works from end to start
28702878
while (p > start)
@@ -2890,6 +2898,11 @@ compile_leader(cctx_T *cctx, char_u *start, char_u *end)
28902898
if (isn == NULL)
28912899
return FAIL;
28922900
}
2901+
else if (numeric_only)
2902+
{
2903+
++p;
2904+
break;
2905+
}
28932906
else
28942907
{
28952908
int invert = TRUE;
@@ -2903,6 +2916,7 @@ compile_leader(cctx_T *cctx, char_u *start, char_u *end)
29032916
return FAIL;
29042917
}
29052918
}
2919+
*end = p;
29062920
return OK;
29072921
}
29082922

@@ -2914,10 +2928,12 @@ compile_leader(cctx_T *cctx, char_u *start, char_u *end)
29142928
compile_subscript(
29152929
char_u **arg,
29162930
cctx_T *cctx,
2917-
char_u **start_leader,
2918-
char_u *end_leader,
2931+
char_u *start_leader,
2932+
char_u **end_leader,
29192933
ppconst_T *ppconst)
29202934
{
2935+
char_u *name_start = *end_leader;
2936+
29212937
for (;;)
29222938
{
29232939
char_u *p = skipwhite(*arg);
@@ -2959,7 +2975,7 @@ compile_subscript(
29592975
*arg = skipwhite(p + 1);
29602976
if (compile_arguments(arg, cctx, &argcount) == FAIL)
29612977
return FAIL;
2962-
if (generate_PCALL(cctx, argcount, end_leader, type, TRUE) == FAIL)
2978+
if (generate_PCALL(cctx, argcount, name_start, type, TRUE) == FAIL)
29632979
return FAIL;
29642980
}
29652981
else if (*p == '-' && p[1] == '>')
@@ -2972,9 +2988,8 @@ compile_subscript(
29722988
// something->method()
29732989
// Apply the '!', '-' and '+' first:
29742990
// -1.0->func() works like (-1.0)->func()
2975-
if (compile_leader(cctx, *start_leader, end_leader) == FAIL)
2991+
if (compile_leader(cctx, TRUE, start_leader, end_leader) == FAIL)
29762992
return FAIL;
2977-
*start_leader = end_leader; // don't apply again later
29782993

29792994
p += 2;
29802995
*arg = skipwhite(p);
@@ -3329,13 +3344,12 @@ compile_expr7(
33293344

33303345
if (rettv->v_type != VAR_UNKNOWN && used_before == ppconst->pp_used)
33313346
{
3332-
// apply the '!', '-' and '+' before the constant
3333-
if (apply_leader(rettv, start_leader, end_leader) == FAIL)
3347+
// apply the '-' and '+' before the constant, but not '!'
3348+
if (apply_leader(rettv, TRUE, start_leader, &end_leader) == FAIL)
33343349
{
33353350
clear_tv(rettv);
33363351
return FAIL;
33373352
}
3338-
start_leader = end_leader; // don't apply again below
33393353

33403354
if (cctx->ctx_skip == SKIP_YES)
33413355
clear_tv(rettv);
@@ -3373,18 +3387,18 @@ compile_expr7(
33733387

33743388
// Handle following "[]", ".member", etc.
33753389
// Then deal with prefixed '-', '+' and '!', if not done already.
3376-
if (compile_subscript(arg, cctx, &start_leader, end_leader,
3390+
if (compile_subscript(arg, cctx, start_leader, &end_leader,
33773391
ppconst) == FAIL)
33783392
return FAIL;
33793393
if (ppconst->pp_used > 0)
33803394
{
33813395
// apply the '!', '-' and '+' before the constant
33823396
rettv = &ppconst->pp_tv[ppconst->pp_used - 1];
3383-
if (apply_leader(rettv, start_leader, end_leader) == FAIL)
3397+
if (apply_leader(rettv, FALSE, start_leader, &end_leader) == FAIL)
33843398
return FAIL;
33853399
return OK;
33863400
}
3387-
if (compile_leader(cctx, start_leader, end_leader) == FAIL)
3401+
if (compile_leader(cctx, FALSE, start_leader, &end_leader) == FAIL)
33883402
return FAIL;
33893403
return OK;
33903404
}

0 commit comments

Comments
 (0)