Patch 8.2.2799
Problem:    Vim9: type casts don't fully work at the script level.
Solution:   Implement the missing piece.
Files:      src/eval.c, src/testdir/test_vim9_expr.vim


*** ../vim-8.2.2798/src/eval.c  2021-04-18 16:08:49.416235259 +0200
--- src/eval.c  2021-04-21 17:27:36.336574801 +0200
***************
*** 51,56 ****
--- 51,57 ----
  static int eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
  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 eval7t(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);
  
***************
*** 3068,3074 ****
      /*
       * Get the first variable.
       */
!     if (eval7(arg, rettv, evalarg, want_string) == FAIL)
        return FAIL;
  
      /*
--- 3069,3075 ----
      /*
       * Get the first variable.
       */
!     if (eval7t(arg, rettv, evalarg, want_string) == FAIL)
        return FAIL;
  
      /*
***************
*** 3141,3147 ****
            return FAIL;
        }
        *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
!       if (eval7(arg, &var2, evalarg, FALSE) == FAIL)
            return FAIL;
  
        if (evaluate)
--- 3142,3148 ----
            return FAIL;
        }
        *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
!       if (eval7t(arg, &var2, evalarg, FALSE) == FAIL)
            return FAIL;
  
        if (evaluate)
***************
*** 3231,3236 ****
--- 3232,3317 ----
      return OK;
  }
  
+ /*
+  * Handle a type cast before a base level expression.
+  * "arg" must point to the first non-white of the expression.
+  * "arg" is advanced to just after the recognized expression.
+  * Return OK or FAIL.
+  */
+     static int
+ eval7t(
+     char_u    **arg,
+     typval_T  *rettv,
+     evalarg_T *evalarg,
+     int               want_string)    // after "." operator
+ {
+     type_T    *want_type = NULL;
+     garray_T  type_list;          // list of pointers to allocated types
+     int               res;
+     int               evaluate = evalarg == NULL ? 0
+                                      : (evalarg->eval_flags & EVAL_EVALUATE);
+ 
+     // Recognize <type> in Vim9 script only.
+     if (in_vim9script() && **arg == '<' && eval_isnamec1((*arg)[1]))
+     {
+       ++*arg;
+       ga_init2(&type_list, sizeof(type_T *), 10);
+       want_type = parse_type(arg, &type_list, TRUE);
+       if (want_type == NULL && (evaluate || **arg != '>'))
+       {
+           clear_type_list(&type_list);
+           return FAIL;
+       }
+ 
+       if (**arg != '>')
+       {
+           if (*skipwhite(*arg) == '>')
+               semsg(_(e_no_white_space_allowed_before_str_str), ">", *arg);
+           else
+               emsg(_(e_missing_gt));
+           clear_type_list(&type_list);
+           return FAIL;
+       }
+       ++*arg;
+       *arg = skipwhite_and_linebreak(*arg, evalarg);
+     }
+ 
+     res = eval7(arg, rettv, evalarg, want_string);
+ 
+     if (want_type != NULL && evaluate)
+     {
+       if (res == OK)
+       {
+           type_T *actual = typval2type(rettv, get_copyID(), &type_list, TRUE);
+ 
+           if (!equal_type(want_type, actual))
+           {
+               if (want_type == &t_bool && actual != &t_bool
+                                       && (actual->tt_flags & TTFLAG_BOOL_OK))
+               {
+                   int n = tv2bool(rettv);
+ 
+                   // can use "0" and "1" for boolean in some places
+                   clear_tv(rettv);
+                   rettv->v_type = VAR_BOOL;
+                   rettv->vval.v_number = n ? VVAL_TRUE : VVAL_FALSE;
+               }
+               else
+               {
+                   where_T where;
+ 
+                   where.wt_index = 0;
+                   where.wt_variable = TRUE;
+                   res = check_type(want_type, actual, TRUE, where);
+               }
+           }
+       }
+       clear_type_list(&type_list);
+     }
+ 
+     return res;
+ }
+ 
      int
  eval_leader(char_u **arg, int vim9)
  {
*** ../vim-8.2.2798/src/testdir/test_vim9_expr.vim      2021-04-11 
20:26:30.486312262 +0200
--- src/testdir/test_vim9_expr.vim      2021-04-21 17:30:22.140131199 +0200
***************
*** 1575,1590 ****
  
  " type casts
  def Test_expr7t()
!   var ls: list<string> = ['a', <string>g:string_empty]
!   var ln: list<number> = [<number>g:anint, <number>g:thefour]
!   var nr = <number>234
!   assert_equal(234, nr)
  
!   CheckDefAndScriptFailure2(["var x = <nr>123"], 'E1010:', 'E15:', 1)
    CheckDefFailure(["var x = <number>"], 'E1097:', 3)
    CheckScriptFailure(['vim9script', "var x = <number>"], 'E15:', 2)
!   CheckDefAndScriptFailure2(["var x = <number >123"], 'E1068:', 'E15:', 1)
!   CheckDefAndScriptFailure2(["var x = <number 123"], 'E1104:', 'E15:', 1)
  enddef
  
  " test low level expression
--- 1575,1599 ----
  
  " type casts
  def Test_expr7t()
!   var lines =<< trim END
!       var ls: list<string> = ['a', <string>g:string_empty]
!       var ln: list<number> = [<number>g:anint, <number>g:thefour]
!       var nr = <number>234
!       assert_equal(234, nr)
!       var text =
!             <string>
!               'text'
!       if false
!         text = <number>'xxx'
!       endif
!   END
!   CheckDefAndScriptSuccess(lines)
  
!   CheckDefAndScriptFailure(["var x = <nr>123"], 'E1010:', 1)
    CheckDefFailure(["var x = <number>"], 'E1097:', 3)
    CheckScriptFailure(['vim9script', "var x = <number>"], 'E15:', 2)
!   CheckDefAndScriptFailure(["var x = <number >123"], 'E1068:', 1)
!   CheckDefAndScriptFailure(["var x = <number 123"], 'E1104:', 1)
  enddef
  
  " test low level expression
*** ../vim-8.2.2798/src/version.c       2021-04-21 16:00:06.711976510 +0200
--- src/version.c       2021-04-21 17:03:07.137615346 +0200
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2799,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
138. You develop a liking for cold coffee.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/202104211558.13LFwBgX1153947%40masaka.moolenaar.net.

Raspunde prin e-mail lui