To: vim_dev@googlegroups.com Subject: Patch 8.2.1067 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 "\') 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 -- Bram@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 ///