Mercurial > vim
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); |