# HG changeset patch # User Bram Moolenaar # Date 1597094103 -7200 # Node ID caf0286cf02b1ed54d84c95bdcb497250a22362c # Parent c7693230fb827a43ef42fe91e0430eeaaaae7371 patch 8.2.1419: Vim9: not operator applied too early Commit: https://github.com/vim/vim/commit/59eccb92e3c68f65525e08d2113213ff7d7ed00a Author: Bram Moolenaar Date: Mon Aug 10 23:09:37 2020 +0200 patch 8.2.1419: Vim9: not operator applied too early Problem: Vim9: not operator applied too early. Solution: Implement the "numeric_only" argument. (closes https://github.com/vim/vim/issues/6680) diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -1744,7 +1744,7 @@ def Test_expr7_call() assert_equal('yes', 'yes'->Echo()) assert_equal('yes', 'yes' ->s:Echo4Arg()) - assert_equal(1, !range(5)->empty()) + assert_equal(true, !range(5)->empty()) assert_equal([0, 1, 2], --3->range()) call CheckDefFailure(["let x = 'yes'->Echo"], 'E107:') @@ -1782,6 +1782,9 @@ def Test_expr7_not() assert_equal(true, !test_void()) assert_equal(true, !test_unknown()) + + assert_equal(false, ![1, 2, 3]->reverse()) + assert_equal(true, ![]->reverse()) END CheckDefSuccess(lines) CheckScriptSuccess(['vim9script'] + lines) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1419, +/**/ 1418, /**/ 1417, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2723,11 +2723,12 @@ compile_get_register(char_u **arg, cctx_ /* * Apply leading '!', '-' and '+' to constant "rettv". + * When "numeric_only" is TRUE do not apply '!'. */ static int -apply_leader(typval_T *rettv, char_u *start, char_u *end) -{ - char_u *p = end; +apply_leader(typval_T *rettv, int numeric_only, char_u *start, char_u **end) +{ + char_u *p = *end; // this works from end to start while (p > start) @@ -2762,6 +2763,11 @@ apply_leader(typval_T *rettv, char_u *st rettv->vval.v_number = val; } } + else if (numeric_only) + { + ++p; + break; + } else { int v = tv2bool(rettv); @@ -2772,6 +2778,7 @@ apply_leader(typval_T *rettv, char_u *st rettv->vval.v_number = v ? VVAL_FALSE : VVAL_TRUE; } } + *end = p; return OK; } @@ -2860,11 +2867,12 @@ get_compare_type(char_u *p, int *len, in /* * Compile code to apply '-', '+' and '!'. + * When "numeric_only" is TRUE do not apply '!'. */ static int -compile_leader(cctx_T *cctx, char_u *start, char_u *end) -{ - char_u *p = end; +compile_leader(cctx_T *cctx, int numeric_only, char_u *start, char_u **end) +{ + char_u *p = *end; // this works from end to start while (p > start) @@ -2890,6 +2898,11 @@ compile_leader(cctx_T *cctx, char_u *sta if (isn == NULL) return FAIL; } + else if (numeric_only) + { + ++p; + break; + } else { int invert = TRUE; @@ -2903,6 +2916,7 @@ compile_leader(cctx_T *cctx, char_u *sta return FAIL; } } + *end = p; return OK; } @@ -2914,10 +2928,12 @@ compile_leader(cctx_T *cctx, char_u *sta compile_subscript( char_u **arg, cctx_T *cctx, - char_u **start_leader, - char_u *end_leader, + char_u *start_leader, + char_u **end_leader, ppconst_T *ppconst) { + char_u *name_start = *end_leader; + for (;;) { char_u *p = skipwhite(*arg); @@ -2959,7 +2975,7 @@ compile_subscript( *arg = skipwhite(p + 1); if (compile_arguments(arg, cctx, &argcount) == FAIL) return FAIL; - if (generate_PCALL(cctx, argcount, end_leader, type, TRUE) == FAIL) + if (generate_PCALL(cctx, argcount, name_start, type, TRUE) == FAIL) return FAIL; } else if (*p == '-' && p[1] == '>') @@ -2972,9 +2988,8 @@ compile_subscript( // something->method() // Apply the '!', '-' and '+' first: // -1.0->func() works like (-1.0)->func() - if (compile_leader(cctx, *start_leader, end_leader) == FAIL) + if (compile_leader(cctx, TRUE, start_leader, end_leader) == FAIL) return FAIL; - *start_leader = end_leader; // don't apply again later p += 2; *arg = skipwhite(p); @@ -3329,13 +3344,12 @@ compile_expr7( if (rettv->v_type != VAR_UNKNOWN && used_before == ppconst->pp_used) { - // apply the '!', '-' and '+' before the constant - if (apply_leader(rettv, start_leader, end_leader) == FAIL) + // apply the '-' and '+' before the constant, but not '!' + if (apply_leader(rettv, TRUE, start_leader, &end_leader) == FAIL) { clear_tv(rettv); return FAIL; } - start_leader = end_leader; // don't apply again below if (cctx->ctx_skip == SKIP_YES) clear_tv(rettv); @@ -3373,18 +3387,18 @@ compile_expr7( // Handle following "[]", ".member", etc. // Then deal with prefixed '-', '+' and '!', if not done already. - if (compile_subscript(arg, cctx, &start_leader, end_leader, + if (compile_subscript(arg, cctx, start_leader, &end_leader, ppconst) == FAIL) return FAIL; if (ppconst->pp_used > 0) { // apply the '!', '-' and '+' before the constant rettv = &ppconst->pp_tv[ppconst->pp_used - 1]; - if (apply_leader(rettv, start_leader, end_leader) == FAIL) + if (apply_leader(rettv, FALSE, start_leader, &end_leader) == FAIL) return FAIL; return OK; } - if (compile_leader(cctx, start_leader, end_leader) == FAIL) + if (compile_leader(cctx, FALSE, start_leader, &end_leader) == FAIL) return FAIL; return OK; }