comparison src/eval.c @ 17763:117c7795a979 v8.1.1878

patch 8.1.1878: negative float before method not parsed correctly commit https://github.com/vim/vim/commit/9cfe8f6e68de4bfb5942d84f4465de914a747b3f Author: Bram Moolenaar <Bram@vim.org> Date: Sat Aug 17 21:04:16 2019 +0200 patch 8.1.1878: negative float before method not parsed correctly Problem: Negative float before method not parsed correctly. Solution: Apply "!" and "-" in front of expression before using ->.
author Bram Moolenaar <Bram@vim.org>
date Sat, 17 Aug 2019 21:15:03 +0200
parents 06c3e15ad84d
children 04245f071792
comparison
equal deleted inserted replaced
17762:87d3311b3401 17763:117c7795a979
239 static int eval3(char_u **arg, typval_T *rettv, int evaluate); 239 static int eval3(char_u **arg, typval_T *rettv, int evaluate);
240 static int eval4(char_u **arg, typval_T *rettv, int evaluate); 240 static int eval4(char_u **arg, typval_T *rettv, int evaluate);
241 static int eval5(char_u **arg, typval_T *rettv, int evaluate); 241 static int eval5(char_u **arg, typval_T *rettv, int evaluate);
242 static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string); 242 static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string);
243 static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string); 243 static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string);
244 static int eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp);
244 245
245 static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate); 246 static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate);
246 static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate); 247 static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate);
247 static int free_unref_items(int copyID); 248 static int free_unref_items(int copyID);
248 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); 249 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate);
1808 error = TRUE; 1809 error = TRUE;
1809 else 1810 else
1810 { 1811 {
1811 /* handle d.key, l[idx], f(expr) */ 1812 /* handle d.key, l[idx], f(expr) */
1812 arg_subsc = arg; 1813 arg_subsc = arg;
1813 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 1814 if (handle_subscript(&arg, &tv, TRUE, TRUE,
1815 name, &name) == FAIL)
1814 error = TRUE; 1816 error = TRUE;
1815 else 1817 else
1816 { 1818 {
1817 if (arg == arg_subsc && len == 2 && name[1] == ':') 1819 if (arg == arg_subsc && len == 2 && name[1] == ':')
1818 { 1820 {
4754 *arg = skipwhite(*arg); 4756 *arg = skipwhite(*arg);
4755 4757
4756 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4758 /* Handle following '[', '(' and '.' for expr[expr], expr.name,
4757 * expr(expr), expr->name(expr) */ 4759 * expr(expr), expr->name(expr) */
4758 if (ret == OK) 4760 if (ret == OK)
4759 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4761 ret = handle_subscript(arg, rettv, evaluate, TRUE,
4762 start_leader, &end_leader);
4760 4763
4761 /* 4764 /*
4762 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4765 * Apply logical NOT and unary '-', from right to left, ignore '+'.
4763 */ 4766 */
4764 if (ret == OK && evaluate && end_leader > start_leader) 4767 if (ret == OK && evaluate && end_leader > start_leader)
4765 { 4768 ret = eval7_leader(rettv, start_leader, &end_leader);
4766 int error = FALSE; 4769 return ret;
4767 varnumber_T val = 0; 4770 }
4771
4772 /*
4773 * Apply the leading "!" and "-" before an eval7 expression to "rettv".
4774 * Adjusts "end_leaderp" until it is at "start_leader".
4775 */
4776 static int
4777 eval7_leader(typval_T *rettv, char_u *start_leader, char_u **end_leaderp)
4778 {
4779 char_u *end_leader = *end_leaderp;
4780 int ret = OK;
4781 int error = FALSE;
4782 varnumber_T val = 0;
4768 #ifdef FEAT_FLOAT 4783 #ifdef FEAT_FLOAT
4769 float_T f = 0.0; 4784 float_T f = 0.0;
4770 4785
4786 if (rettv->v_type == VAR_FLOAT)
4787 f = rettv->vval.v_float;
4788 else
4789 #endif
4790 val = tv_get_number_chk(rettv, &error);
4791 if (error)
4792 {
4793 clear_tv(rettv);
4794 ret = FAIL;
4795 }
4796 else
4797 {
4798 while (end_leader > start_leader)
4799 {
4800 --end_leader;
4801 if (*end_leader == '!')
4802 {
4803 #ifdef FEAT_FLOAT
4804 if (rettv->v_type == VAR_FLOAT)
4805 f = !f;
4806 else
4807 #endif
4808 val = !val;
4809 }
4810 else if (*end_leader == '-')
4811 {
4812 #ifdef FEAT_FLOAT
4813 if (rettv->v_type == VAR_FLOAT)
4814 f = -f;
4815 else
4816 #endif
4817 val = -val;
4818 }
4819 }
4820 #ifdef FEAT_FLOAT
4771 if (rettv->v_type == VAR_FLOAT) 4821 if (rettv->v_type == VAR_FLOAT)
4772 f = rettv->vval.v_float; 4822 {
4823 clear_tv(rettv);
4824 rettv->vval.v_float = f;
4825 }
4773 else 4826 else
4774 #endif 4827 #endif
4775 val = tv_get_number_chk(rettv, &error);
4776 if (error)
4777 { 4828 {
4778 clear_tv(rettv); 4829 clear_tv(rettv);
4779 ret = FAIL; 4830 rettv->v_type = VAR_NUMBER;
4780 } 4831 rettv->vval.v_number = val;
4781 else 4832 }
4782 { 4833 }
4783 while (end_leader > start_leader) 4834 *end_leaderp = end_leader;
4784 {
4785 --end_leader;
4786 if (*end_leader == '!')
4787 {
4788 #ifdef FEAT_FLOAT
4789 if (rettv->v_type == VAR_FLOAT)
4790 f = !f;
4791 else
4792 #endif
4793 val = !val;
4794 }
4795 else if (*end_leader == '-')
4796 {
4797 #ifdef FEAT_FLOAT
4798 if (rettv->v_type == VAR_FLOAT)
4799 f = -f;
4800 else
4801 #endif
4802 val = -val;
4803 }
4804 }
4805 #ifdef FEAT_FLOAT
4806 if (rettv->v_type == VAR_FLOAT)
4807 {
4808 clear_tv(rettv);
4809 rettv->vval.v_float = f;
4810 }
4811 else
4812 #endif
4813 {
4814 clear_tv(rettv);
4815 rettv->v_type = VAR_NUMBER;
4816 rettv->vval.v_number = val;
4817 }
4818 }
4819 }
4820
4821 return ret; 4835 return ret;
4822 } 4836 }
4823 4837
4824 /* 4838 /*
4825 * Call the function referred to in "rettv". 4839 * Call the function referred to in "rettv".
7537 */ 7551 */
7538 int 7552 int
7539 handle_subscript( 7553 handle_subscript(
7540 char_u **arg, 7554 char_u **arg,
7541 typval_T *rettv, 7555 typval_T *rettv,
7542 int evaluate, /* do more than finding the end */ 7556 int evaluate, // do more than finding the end
7543 int verbose) /* give error messages */ 7557 int verbose, // give error messages
7558 char_u *start_leader, // start of '!' and '-' prefixes
7559 char_u **end_leaderp) // end of '!' and '-' prefixes
7544 { 7560 {
7545 int ret = OK; 7561 int ret = OK;
7546 dict_T *selfdict = NULL; 7562 dict_T *selfdict = NULL;
7547 7563
7548 // "." is ".name" lookup when we found a dict or when evaluating and 7564 // "." is ".name" lookup when we found a dict or when evaluating and
7574 dict_unref(selfdict); 7590 dict_unref(selfdict);
7575 selfdict = NULL; 7591 selfdict = NULL;
7576 } 7592 }
7577 else if (**arg == '-') 7593 else if (**arg == '-')
7578 { 7594 {
7579 if ((*arg)[2] == '{') 7595 // Expression "-1.0->method()" applies the leader "-" before
7580 // expr->{lambda}() 7596 // applying ->.
7581 ret = eval_lambda(arg, rettv, evaluate, verbose); 7597 if (evaluate && *end_leaderp > start_leader)
7582 else 7598 ret = eval7_leader(rettv, start_leader, end_leaderp);
7583 // expr->name() 7599 if (ret == OK)
7584 ret = eval_method(arg, rettv, evaluate, verbose); 7600 {
7601 if ((*arg)[2] == '{')
7602 // expr->{lambda}()
7603 ret = eval_lambda(arg, rettv, evaluate, verbose);
7604 else
7605 // expr->name()
7606 ret = eval_method(arg, rettv, evaluate, verbose);
7607 }
7585 } 7608 }
7586 else /* **arg == '[' || **arg == '.' */ 7609 else /* **arg == '[' || **arg == '.' */
7587 { 7610 {
7588 dict_unref(selfdict); 7611 dict_unref(selfdict);
7589 if (rettv->v_type == VAR_DICT) 7612 if (rettv->v_type == VAR_DICT)
9801 name = tofree; 9824 name = tofree;
9802 n = (get_var_tv(name, len, &tv, NULL, FALSE, TRUE) == OK); 9825 n = (get_var_tv(name, len, &tv, NULL, FALSE, TRUE) == OK);
9803 if (n) 9826 if (n)
9804 { 9827 {
9805 /* handle d.key, l[idx], f(expr) */ 9828 /* handle d.key, l[idx], f(expr) */
9806 n = (handle_subscript(&var, &tv, TRUE, FALSE) == OK); 9829 n = (handle_subscript(&var, &tv, TRUE, FALSE, name, &name) == OK);
9807 if (n) 9830 if (n)
9808 clear_tv(&tv); 9831 clear_tv(&tv);
9809 } 9832 }
9810 } 9833 }
9811 if (*var != NUL) 9834 if (*var != NUL)