Patch 8.1.1878
Problem:    Negative float before method not parsed correctly.
Solution:   Apply "!" and "-" in front of expression before using ->.
Files:      src/eval.c, src/proto/eval.pro, src/userfunc.c,
            src/testdir/test_method.vim


*** ../vim-8.1.1877/src/eval.c  2019-08-09 23:25:02.636657233 +0200
--- src/eval.c  2019-08-17 20:57:42.571858569 +0200
***************
*** 241,246 ****
--- 241,247 ----
  static int eval5(char_u **arg, typval_T *rettv, int evaluate);
  static int eval6(char_u **arg, typval_T *rettv, int evaluate, int 
want_string);
  static int eval7(char_u **arg, typval_T *rettv, int evaluate, int 
want_string);
+ static int eval7_leader(typval_T *rettv, char_u *start_leader, char_u 
**end_leaderp);
  
  static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate);
  static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate);
***************
*** 1810,1816 ****
                {
                    /* handle d.key, l[idx], f(expr) */
                    arg_subsc = arg;
!                   if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL)
                        error = TRUE;
                    else
                    {
--- 1811,1818 ----
                {
                    /* handle d.key, l[idx], f(expr) */
                    arg_subsc = arg;
!                   if (handle_subscript(&arg, &tv, TRUE, TRUE,
!                                                         name, &name) == FAIL)
                        error = TRUE;
                    else
                    {
***************
*** 4756,4823 ****
      /* Handle following '[', '(' and '.' for expr[expr], expr.name,
       * expr(expr), expr->name(expr) */
      if (ret == OK)
!       ret = handle_subscript(arg, rettv, evaluate, TRUE);
  
      /*
       * Apply logical NOT and unary '-', from right to left, ignore '+'.
       */
      if (ret == OK && evaluate && end_leader > start_leader)
!     {
!       int         error = FALSE;
!       varnumber_T val = 0;
  #ifdef FEAT_FLOAT
!       float_T     f = 0.0;
  
!       if (rettv->v_type == VAR_FLOAT)
!           f = rettv->vval.v_float;
!       else
  #endif
!           val = tv_get_number_chk(rettv, &error);
!       if (error)
!       {
!           clear_tv(rettv);
!           ret = FAIL;
!       }
!       else
        {
!           while (end_leader > start_leader)
            {
-               --end_leader;
-               if (*end_leader == '!')
-               {
  #ifdef FEAT_FLOAT
!                   if (rettv->v_type == VAR_FLOAT)
!                       f = !f;
!                   else
  #endif
!                       val = !val;
!               }
!               else if (*end_leader == '-')
!               {
  #ifdef FEAT_FLOAT
!                   if (rettv->v_type == VAR_FLOAT)
!                       f = -f;
!                   else
  #endif
!                       val = -val;
!               }
            }
  #ifdef FEAT_FLOAT
!           if (rettv->v_type == VAR_FLOAT)
!           {
!               clear_tv(rettv);
!               rettv->vval.v_float = f;
!           }
!           else
  #endif
!           {
!               clear_tv(rettv);
!               rettv->v_type = VAR_NUMBER;
!               rettv->vval.v_number = val;
!           }
        }
      }
! 
      return ret;
  }
  
--- 4758,4837 ----
      /* Handle following '[', '(' and '.' for expr[expr], expr.name,
       * expr(expr), expr->name(expr) */
      if (ret == OK)
!       ret = handle_subscript(arg, rettv, evaluate, 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;
!     int               error = FALSE;
!     varnumber_T val = 0;
  #ifdef FEAT_FLOAT
!     float_T       f = 0.0;
  
!     if (rettv->v_type == VAR_FLOAT)
!       f = rettv->vval.v_float;
!     else
  #endif
!       val = tv_get_number_chk(rettv, &error);
!     if (error)
!     {
!       clear_tv(rettv);
!       ret = FAIL;
!     }
!     else
!     {
!       while (end_leader > start_leader)
        {
!           --end_leader;
!           if (*end_leader == '!')
            {
  #ifdef FEAT_FLOAT
!               if (rettv->v_type == VAR_FLOAT)
!                   f = !f;
!               else
  #endif
!                   val = !val;
!           }
!           else if (*end_leader == '-')
!           {
  #ifdef FEAT_FLOAT
!               if (rettv->v_type == VAR_FLOAT)
!                   f = -f;
!               else
  #endif
!                   val = -val;
            }
+       }
  #ifdef FEAT_FLOAT
!       if (rettv->v_type == VAR_FLOAT)
!       {
!           clear_tv(rettv);
!           rettv->vval.v_float = f;
!       }
!       else
  #endif
!       {
!           clear_tv(rettv);
!           rettv->v_type = VAR_NUMBER;
!           rettv->vval.v_number = val;
        }
      }
!     *end_leaderp = end_leader;
      return ret;
  }
  
***************
*** 7539,7546 ****
  handle_subscript(
      char_u    **arg,
      typval_T  *rettv,
!     int               evaluate,       /* do more than finding the end */
!     int               verbose)        /* give error messages */
  {
      int               ret = OK;
      dict_T    *selfdict = NULL;
--- 7553,7562 ----
  handle_subscript(
      char_u    **arg,
      typval_T  *rettv,
!     int               evaluate,       // 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               ret = OK;
      dict_T    *selfdict = NULL;
***************
*** 7576,7587 ****
        }
        else if (**arg == '-')
        {
!           if ((*arg)[2] == '{')
!               // expr->{lambda}()
!               ret = eval_lambda(arg, rettv, evaluate, verbose);
!           else
!               // expr->name()
!               ret = eval_method(arg, rettv, evaluate, verbose);
        }
        else /* **arg == '[' || **arg == '.' */
        {
--- 7592,7610 ----
        }
        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] == '{')
!                   // expr->{lambda}()
!                   ret = eval_lambda(arg, rettv, evaluate, verbose);
!               else
!                   // expr->name()
!                   ret = eval_method(arg, rettv, evaluate, verbose);
!           }
        }
        else /* **arg == '[' || **arg == '.' */
        {
***************
*** 9803,9809 ****
        if (n)
        {
            /* handle d.key, l[idx], f(expr) */
!           n = (handle_subscript(&var, &tv, TRUE, FALSE) == OK);
            if (n)
                clear_tv(&tv);
        }
--- 9826,9832 ----
        if (n)
        {
            /* handle d.key, l[idx], f(expr) */
!           n = (handle_subscript(&var, &tv, TRUE, FALSE, name, &name) == OK);
            if (n)
                clear_tv(&tv);
        }
*** ../vim-8.1.1877/src/proto/eval.pro  2019-07-28 14:15:21.330943640 +0200
--- src/proto/eval.pro  2019-08-17 20:49:25.598652264 +0200
***************
*** 85,91 ****
  char_u *v_throwpoint(char_u *oldval);
  char_u *set_cmdarg(exarg_T *eap, char_u *oldarg);
  int get_var_tv(char_u *name, int len, typval_T *rettv, dictitem_T **dip, int 
verbose, int no_autoload);
! int handle_subscript(char_u **arg, typval_T *rettv, int evaluate, int 
verbose);
  typval_T *alloc_tv(void);
  void free_tv(typval_T *varp);
  void clear_tv(typval_T *varp);
--- 85,91 ----
  char_u *v_throwpoint(char_u *oldval);
  char_u *set_cmdarg(exarg_T *eap, char_u *oldarg);
  int get_var_tv(char_u *name, int len, typval_T *rettv, dictitem_T **dip, int 
verbose, int no_autoload);
! int handle_subscript(char_u **arg, typval_T *rettv, int evaluate, int 
verbose, char_u *start_leader, char_u **end_leaderp);
  typval_T *alloc_tv(void);
  void free_tv(typval_T *varp);
  void clear_tv(typval_T *varp);
*** ../vim-8.1.1877/src/userfunc.c      2019-08-16 22:22:27.915986997 +0200
--- src/userfunc.c      2019-08-17 20:49:00.106813103 +0200
***************
*** 3165,3172 ****
        if (has_watchexpr())
            dbg_check_breakpoint(eap);
  
!       /* Handle a function returning a Funcref, Dictionary or List. */
!       if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL)
        {
            failed = TRUE;
            break;
--- 3165,3173 ----
        if (has_watchexpr())
            dbg_check_breakpoint(eap);
  
!       // Handle a function returning a Funcref, Dictionary or List.
!       if (handle_subscript(&arg, &rettv, !eap->skip, TRUE,
!                                                         name, &name) == FAIL)
        {
            failed = TRUE;
            break;
*** ../vim-8.1.1877/src/testdir/test_method.vim 2019-08-16 22:22:27.915986997 
+0200
--- src/testdir/test_method.vim 2019-08-17 20:51:11.705986816 +0200
***************
*** 115,120 ****
--- 115,125 ----
    delfunc Concat
  endfunc
  
+ func Test_method_float()
+   eval 1.234->string()->assert_equal('1.234')
+   eval -1.234->string()->assert_equal('-1.234')
+ endfunc
+ 
  func Test_method_syntax()
    eval [1, 2, 3]  ->sort( )
    eval [1, 2, 3]  
*** ../vim-8.1.1877/src/version.c       2019-08-17 20:17:48.081707408 +0200
--- src/version.c       2019-08-17 21:03:17.754448200 +0200
***************
*** 771,772 ****
--- 771,774 ----
  {   /* Add new patch number below this line */
+ /**/
+     1878,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
88. Every single time you press the 'Get mail' button...it does get new mail.

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201908171904.x7HJ4hi0028929%40masaka.moolenaar.net.

Raspunde prin e-mail lui