comparison src/eval.c @ 21032:f80e822a310d v8.2.1067

patch 8.2.1067: expression "!expr->func()" does not work Commit: https://github.com/vim/vim/commit/0b1cd52ff6bf690388f892be686a91721a082e55 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jun 27 13:11:50 2020 +0200 patch 8.2.1067: expression "!expr->func()" does not work Problem: Expression "!expr->func()" does not work. Solution: Apply plus and minus earlier. (closes https://github.com/vim/vim/issues/6348)
author Bram Moolenaar <Bram@vim.org>
date Sat, 27 Jun 2020 13:15:03 +0200
parents 7acceb76669f
children 2f8b0812819f
comparison
equal deleted inserted replaced
21031:d49456e1977e 21032:f80e822a310d
49 static int eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg); 49 static int eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
50 static int eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg); 50 static int eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
51 static int eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg); 51 static int eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
52 static int eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string); 52 static int eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
53 static int eval7(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string); 53 static int eval7(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
54 static int eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp); 54 static int eval7_leader(typval_T *rettv, int numeric_only, char_u *start_leader, char_u **end_leaderp);
55 55
56 static int free_unref_items(int copyID); 56 static int free_unref_items(int copyID);
57 static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end); 57 static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end);
58 58
59 /* 59 /*
2754 case '6': 2754 case '6':
2755 case '7': 2755 case '7':
2756 case '8': 2756 case '8':
2757 case '9': 2757 case '9':
2758 case '.': ret = get_number_tv(arg, rettv, evaluate, want_string); 2758 case '.': ret = get_number_tv(arg, rettv, evaluate, want_string);
2759
2760 // Apply prefixed "-" and "+" now. Matters especially when
2761 // "->" follows.
2762 if (ret == OK && evaluate && end_leader > start_leader)
2763 ret = eval7_leader(rettv, TRUE, start_leader, &end_leader);
2759 break; 2764 break;
2760 2765
2761 /* 2766 /*
2762 * String constant: "string". 2767 * String constant: "string".
2763 */ 2768 */
2877 *arg = skipwhite(*arg); 2882 *arg = skipwhite(*arg);
2878 2883
2879 // Handle following '[', '(' and '.' for expr[expr], expr.name, 2884 // Handle following '[', '(' and '.' for expr[expr], expr.name,
2880 // expr(expr), expr->name(expr) 2885 // expr(expr), expr->name(expr)
2881 if (ret == OK) 2886 if (ret == OK)
2882 ret = handle_subscript(arg, rettv, flags, TRUE, 2887 ret = handle_subscript(arg, rettv, flags, TRUE);
2883 start_leader, &end_leader);
2884 2888
2885 /* 2889 /*
2886 * Apply logical NOT and unary '-', from right to left, ignore '+'. 2890 * Apply logical NOT and unary '-', from right to left, ignore '+'.
2887 */ 2891 */
2888 if (ret == OK && evaluate && end_leader > start_leader) 2892 if (ret == OK && evaluate && end_leader > start_leader)
2889 ret = eval7_leader(rettv, start_leader, &end_leader); 2893 ret = eval7_leader(rettv, FALSE, start_leader, &end_leader);
2890 return ret; 2894 return ret;
2891 } 2895 }
2892 2896
2893 /* 2897 /*
2894 * Apply the leading "!" and "-" before an eval7 expression to "rettv". 2898 * Apply the leading "!" and "-" before an eval7 expression to "rettv".
2899 * When "numeric_only" is TRUE only handle "+" and "-".
2895 * Adjusts "end_leaderp" until it is at "start_leader". 2900 * Adjusts "end_leaderp" until it is at "start_leader".
2896 */ 2901 */
2897 static int 2902 static int
2898 eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp) 2903 eval7_leader(
2904 typval_T *rettv,
2905 int numeric_only,
2906 char_u *start_leader,
2907 char_u **end_leaderp)
2899 { 2908 {
2900 char_u *end_leader = *end_leaderp; 2909 char_u *end_leader = *end_leaderp;
2901 int ret = OK; 2910 int ret = OK;
2902 int error = FALSE; 2911 int error = FALSE;
2903 varnumber_T val = 0; 2912 varnumber_T val = 0;
2919 while (end_leader > start_leader) 2928 while (end_leader > start_leader)
2920 { 2929 {
2921 --end_leader; 2930 --end_leader;
2922 if (*end_leader == '!') 2931 if (*end_leader == '!')
2923 { 2932 {
2933 if (numeric_only)
2934 {
2935 ++end_leader;
2936 break;
2937 }
2924 #ifdef FEAT_FLOAT 2938 #ifdef FEAT_FLOAT
2925 if (rettv->v_type == VAR_FLOAT) 2939 if (rettv->v_type == VAR_FLOAT)
2926 f = !f; 2940 f = !f;
2927 else 2941 else
2928 #endif 2942 #endif
4869 int 4883 int
4870 handle_subscript( 4884 handle_subscript(
4871 char_u **arg, 4885 char_u **arg,
4872 typval_T *rettv, 4886 typval_T *rettv,
4873 int flags, // do more than finding the end 4887 int flags, // do more than finding the end
4874 int verbose, // give error messages 4888 int verbose) // give error messages
4875 char_u *start_leader, // start of '!' and '-' prefixes
4876 char_u **end_leaderp) // end of '!' and '-' prefixes
4877 { 4889 {
4878 int evaluate = flags & EVAL_EVALUATE; 4890 int evaluate = flags & EVAL_EVALUATE;
4879 int ret = OK; 4891 int ret = OK;
4880 dict_T *selfdict = NULL; 4892 dict_T *selfdict = NULL;
4881 4893
4908 dict_unref(selfdict); 4920 dict_unref(selfdict);
4909 selfdict = NULL; 4921 selfdict = NULL;
4910 } 4922 }
4911 else if (**arg == '-') 4923 else if (**arg == '-')
4912 { 4924 {
4913 // Expression "-1.0->method()" applies the leader "-" before
4914 // applying ->.
4915 if (evaluate && *end_leaderp > start_leader)
4916 ret = eval7_leader(rettv, start_leader, end_leaderp);
4917 if (ret == OK) 4925 if (ret == OK)
4918 { 4926 {
4919 if ((*arg)[2] == '{') 4927 if ((*arg)[2] == '{')
4920 // expr->{lambda}() 4928 // expr->{lambda}()
4921 ret = eval_lambda(arg, rettv, evaluate, verbose); 4929 ret = eval_lambda(arg, rettv, evaluate, verbose);