Patch 8.2.2250
Problem:    Vim9: sublist is ambiguous.
Solution:   Require white space around the colon. (closes #7409)
Files:      src/vim9compile.c, src/eval.c, src/testdir/test_vim9_expr.vim,
            src/testdir/test_vim9_disassemble.vim


*** ../vim-8.2.2249/src/vim9compile.c   2020-12-28 20:53:17.499051882 +0100
--- src/vim9compile.c   2020-12-30 19:17:47.474873324 +0100
***************
*** 3695,3713 ****
            if (may_get_next_line_error(p, arg, cctx) == FAIL)
                return FAIL;
            if (**arg == ':')
                // missing first index is equal to zero
                generate_PUSHNR(cctx, 0);
            else
            {
                if (compile_expr0(arg, cctx) == FAIL)
                    return FAIL;
                if (may_get_next_line_error(p, arg, cctx) == FAIL)
                    return FAIL;
                *arg = skipwhite(*arg);
            }
            if (**arg == ':')
            {
!               *arg = skipwhite(*arg + 1);
                if (may_get_next_line_error(p, arg, cctx) == FAIL)
                    return FAIL;
                if (**arg == ']')
--- 3695,3727 ----
            if (may_get_next_line_error(p, arg, cctx) == FAIL)
                return FAIL;
            if (**arg == ':')
+           {
                // missing first index is equal to zero
                generate_PUSHNR(cctx, 0);
+           }
            else
            {
                if (compile_expr0(arg, cctx) == FAIL)
                    return FAIL;
+               if (**arg == ':')
+               {
+                   semsg(_(e_white_space_required_before_and_after_str), ":");
+                   return FAIL;
+               }
                if (may_get_next_line_error(p, arg, cctx) == FAIL)
                    return FAIL;
                *arg = skipwhite(*arg);
            }
            if (**arg == ':')
            {
!               is_slice = TRUE;
!               ++*arg;
!               if (!IS_WHITE_OR_NUL(**arg) && **arg != ']')
!               {
!                   semsg(_(e_white_space_required_before_and_after_str), ":");
!                   return FAIL;
!               }
!               *arg = skipwhite(*arg);
                if (may_get_next_line_error(p, arg, cctx) == FAIL)
                    return FAIL;
                if (**arg == ']')
***************
*** 3721,3727 ****
                        return FAIL;
                    *arg = skipwhite(*arg);
                }
-               is_slice = TRUE;
            }
  
            if (**arg != ']')
--- 3735,3740 ----
*** ../vim-8.2.2249/src/eval.c  2020-12-25 15:24:19.902942195 +0100
--- src/eval.c  2020-12-30 20:27:09.415850475 +0100
***************
*** 3725,3730 ****
--- 3725,3731 ----
      int               range = FALSE;
      char_u    *key = NULL;
      int               keylen = -1;
+     int               vim9 = in_vim9script();
  
      if (check_can_index(rettv, evaluate, verbose) == FAIL)
        return FAIL;
***************
*** 3755,3760 ****
--- 3756,3767 ----
            empty1 = TRUE;
        else if (eval1(arg, &var1, evalarg) == FAIL)    // recursive!
            return FAIL;
+       else if (vim9 && **arg == ':')
+       {
+           semsg(_(e_white_space_required_before_and_after_str), ":");
+           clear_tv(&var1);
+           return FAIL;
+       }
        else if (evaluate && tv_get_string_chk(&var1) == NULL)
        {
            // not a number or string
***************
*** 3769,3775 ****
        if (**arg == ':')
        {
            range = TRUE;
!           *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
            if (**arg == ']')
                empty2 = TRUE;
            else if (eval1(arg, &var2, evalarg) == FAIL)        // recursive!
--- 3776,3790 ----
        if (**arg == ':')
        {
            range = TRUE;
!           ++*arg;
!           if (!IS_WHITE_OR_NUL(**arg) && **arg != ']')
!           {
!               semsg(_(e_white_space_required_before_and_after_str), ":");
!               if (!empty1)
!                   clear_tv(&var1);
!               return FAIL;
!           }
!           *arg = skipwhite_and_linebreak(*arg, evalarg);
            if (**arg == ']')
                empty2 = TRUE;
            else if (eval1(arg, &var2, evalarg) == FAIL)        // recursive!
*** ../vim-8.2.2249/src/testdir/test_vim9_expr.vim      2020-12-27 
14:43:23.497570151 +0100
--- src/testdir/test_vim9_expr.vim      2020-12-30 20:34:40.110394003 +0100
***************
*** 1718,1723 ****
--- 1718,1732 ----
        Main()
    END
    CheckScriptFailure(lines, 'E1127:')
+ 
+   lines =<< trim END
+       var numbers = [1, 2, 3, 4]
+       var a = 1
+       var b = 2
+   END
+   CheckDefAndScriptFailure(lines + ['echo numbers[1:b]'], 'E1004:', 4)
+   CheckDefAndScriptFailure(lines + ['echo numbers[1: b]'], 'E1004:', 4)
+   CheckDefAndScriptFailure(lines + ['echo numbers[a :b]'], 'E1004:', 4)
  enddef
  
  def Test_expr7_list_vim9script()
***************
*** 2274,2286 ****
      assert_equal('', g:teststring[-1])
      assert_equal('', g:teststring[99])
  
!     assert_equal('b', g:teststring[1:1])
!     assert_equal('bcdef', g:teststring[1:])
!     assert_equal('abcd', g:teststring[:3])
!     assert_equal('cdef', g:teststring[-4:])
!     assert_equal('abcdef', g:teststring[-9:])
!     assert_equal('abcd', g:teststring[:-3])
!     assert_equal('', g:teststring[:-9])
  
      # blob index cannot be out of range
      g:testblob = 0z01ab
--- 2283,2295 ----
      assert_equal('', g:teststring[-1])
      assert_equal('', g:teststring[99])
  
!     assert_equal('b', g:teststring[1 : 1])
!     assert_equal('bcdef', g:teststring[1 :])
!     assert_equal('abcd', g:teststring[: 3])
!     assert_equal('cdef', g:teststring[-4 :])
!     assert_equal('abcdef', g:teststring[-9 :])
!     assert_equal('abcd', g:teststring[: -3])
!     assert_equal('', g:teststring[: -9])
  
      # blob index cannot be out of range
      g:testblob = 0z01ab
***************
*** 2290,2302 ****
      assert_equal(0x01, g:testblob[-2])
  
      # blob slice accepts out of range
!     assert_equal(0z01ab, g:testblob[0:1])
!     assert_equal(0z01, g:testblob[0:0])
!     assert_equal(0z01, g:testblob[-2:-2])
!     assert_equal(0zab, g:testblob[1:1])
!     assert_equal(0zab, g:testblob[-1:-1])
!     assert_equal(0z, g:testblob[2:2])
!     assert_equal(0z, g:testblob[0:-3])
  
      # list index cannot be out of range
      g:testlist = [0, 1, 2, 3]
--- 2299,2311 ----
      assert_equal(0x01, g:testblob[-2])
  
      # blob slice accepts out of range
!     assert_equal(0z01ab, g:testblob[0 : 1])
!     assert_equal(0z01, g:testblob[0 : 0])
!     assert_equal(0z01, g:testblob[-2 : -2])
!     assert_equal(0zab, g:testblob[1 : 1])
!     assert_equal(0zab, g:testblob[-1 : -1])
!     assert_equal(0z, g:testblob[2 : 2])
!     assert_equal(0z, g:testblob[0 : -3])
  
      # list index cannot be out of range
      g:testlist = [0, 1, 2, 3]
***************
*** 2308,2326 ****
      assert_equal(1, g:testlist[g:theone])
  
      # list slice accepts out of range
!     assert_equal([0], g:testlist[0:0])
!     assert_equal([3], g:testlist[3:3])
!     assert_equal([0, 1], g:testlist[0:1])
!     assert_equal([0, 1, 2, 3], g:testlist[0:3])
!     assert_equal([0, 1, 2, 3], g:testlist[0:9])
!     assert_equal([], g:testlist[-1:1])
!     assert_equal([1], g:testlist[-3:1])
!     assert_equal([0, 1], g:testlist[-4:1])
!     assert_equal([0, 1], g:testlist[-9:1])
!     assert_equal([1, 2, 3], g:testlist[1:-1])
!     assert_equal([1], g:testlist[1:-3])
!     assert_equal([], g:testlist[1:-4])
!     assert_equal([], g:testlist[1:-9])
  
      g:testdict = {a: 1, b: 2}
      assert_equal(1, g:testdict['a'])
--- 2317,2335 ----
      assert_equal(1, g:testlist[g:theone])
  
      # list slice accepts out of range
!     assert_equal([0], g:testlist[0 : 0])
!     assert_equal([3], g:testlist[3 : 3])
!     assert_equal([0, 1], g:testlist[0 : 1])
!     assert_equal([0, 1, 2, 3], g:testlist[0 : 3])
!     assert_equal([0, 1, 2, 3], g:testlist[0 : 9])
!     assert_equal([], g:testlist[-1 : 1])
!     assert_equal([1], g:testlist[-3 : 1])
!     assert_equal([0, 1], g:testlist[-4 : 1])
!     assert_equal([0, 1], g:testlist[-9 : 1])
!     assert_equal([1, 2, 3], g:testlist[1 : -1])
!     assert_equal([1], g:testlist[1 : -3])
!     assert_equal([], g:testlist[1 : -4])
!     assert_equal([], g:testlist[1 : -9])
  
      g:testdict = {a: 1, b: 2}
      assert_equal(1, g:testdict['a'])
***************
*** 2340,2347 ****
    CheckDefExecFailure(['echo g:testlist[-5]'], 'E684:', 1)
    CheckScriptFailure(['vim9script', 'echo g:testlist[-5]'], 'E684:', 2)
  
!   CheckDefExecFailure(['echo g:testdict["a":"b"]'], 'E719:', 1)
!   CheckScriptFailure(['vim9script', 'echo g:testdict["a":"b"]'], 'E719:', 2)
    CheckDefExecFailure(['echo g:testdict[1]'], 'E716:', 1)
    CheckScriptFailure(['vim9script', 'echo g:testdict[1]'], 'E716:', 2)
  
--- 2349,2356 ----
    CheckDefExecFailure(['echo g:testlist[-5]'], 'E684:', 1)
    CheckScriptFailure(['vim9script', 'echo g:testlist[-5]'], 'E684:', 2)
  
!   CheckDefExecFailure(['echo g:testdict["a" : "b"]'], 'E719:', 1)
!   CheckScriptFailure(['vim9script', 'echo g:testdict["a" : "b"]'], 'E719:', 2)
    CheckDefExecFailure(['echo g:testdict[1]'], 'E716:', 1)
    CheckScriptFailure(['vim9script', 'echo g:testdict[1]'], 'E716:', 2)
  
***************
*** 2746,2790 ****
      assert_equal('', text[6])
      assert_equal('', text[999])
  
!     assert_equal('ábçdëf', text[0:-1])
!     assert_equal('ábçdëf', text[0 :-1])
!     assert_equal('ábçdëf', text[0: -1])
      assert_equal('ábçdëf', text[0 : -1])
      assert_equal('ábçdëf', text[0
!                   :-1])
!     assert_equal('ábçdëf', text[0:
                    -1])
      assert_equal('ábçdëf', text[0 : -1
                    ])
!     assert_equal('bçdëf', text[1:-1])
!     assert_equal('çdëf', text[2:-1])
!     assert_equal('dëf', text[3:-1])
!     assert_equal('ëf', text[4:-1])
!     assert_equal('f', text[5:-1])
!     assert_equal('', text[6:-1])
!     assert_equal('', text[999:-1])
  
!     assert_equal('ábçd', text[:3])
!     assert_equal('bçdëf', text[1:])
      assert_equal('ábçdëf', text[:])
    END
    CheckDefSuccess(lines)
    CheckScriptSuccess(['vim9script'] + lines)
  
    lines =<< trim END
!       var d = 'asdf'[1:
    END
    CheckDefFailure(lines, 'E1097:', 3)
    lines =<< trim END
!       var d = 'asdf'[1:xxx]
    END
    CheckDefFailure(lines, 'E1001:', 1)
    lines =<< trim END
!       var d = 'asdf'[1:2
    END
    CheckDefFailure(lines, 'E1097:', 3)
    lines =<< trim END
!       var d = 'asdf'[1:2
        echo d
    END
    CheckDefFailure(lines, 'E111:', 2)
--- 2755,2799 ----
      assert_equal('', text[6])
      assert_equal('', text[999])
  
!     assert_equal('ábçdëf', text[0 : -1])
!     assert_equal('ábçdëf', text[0 : -1])
!     assert_equal('ábçdëf', text[0 : -1])
      assert_equal('ábçdëf', text[0 : -1])
      assert_equal('ábçdëf', text[0
!                   : -1])
!     assert_equal('ábçdëf', text[0 :
                    -1])
      assert_equal('ábçdëf', text[0 : -1
                    ])
!     assert_equal('bçdëf', text[1 : -1])
!     assert_equal('çdëf', text[2 : -1])
!     assert_equal('dëf', text[3 : -1])
!     assert_equal('ëf', text[4 : -1])
!     assert_equal('f', text[5 : -1])
!     assert_equal('', text[6 : -1])
!     assert_equal('', text[999 : -1])
  
!     assert_equal('ábçd', text[: 3])
!     assert_equal('bçdëf', text[1 :])
      assert_equal('ábçdëf', text[:])
    END
    CheckDefSuccess(lines)
    CheckScriptSuccess(['vim9script'] + lines)
  
    lines =<< trim END
!       var d = 'asdf'[1 :
    END
    CheckDefFailure(lines, 'E1097:', 3)
    lines =<< trim END
!       var d = 'asdf'[1 : xxx]
    END
    CheckDefFailure(lines, 'E1001:', 1)
    lines =<< trim END
!       var d = 'asdf'[1 : 2
    END
    CheckDefFailure(lines, 'E1097:', 3)
    lines =<< trim END
!       var d = 'asdf'[1 : 2
        echo d
    END
    CheckDefFailure(lines, 'E111:', 2)
***************
*** 2794,2805 ****
    END
    CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got 
string', 1)
    lines =<< trim END
!       var d = 'asdf'['1':2]
        echo d
    END
    CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got 
string', 1)
    lines =<< trim END
!       var d = 'asdf'[1:'2']
        echo d
    END
    CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got 
string', 1)
--- 2803,2814 ----
    END
    CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got 
string', 1)
    lines =<< trim END
!       var d = 'asdf'['1' : 2]
        echo d
    END
    CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got 
string', 1)
    lines =<< trim END
!       var d = 'asdf'[1 : '2']
        echo d
    END
    CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got 
string', 1)
***************
*** 2813,2834 ****
      assert_equal(4, list[-1])
      assert_equal(0, list[-5])
  
!     assert_equal([0, 1, 2, 3, 4], list[0:4])
      assert_equal([0, 1, 2, 3, 4], list[:])
!     assert_equal([1, 2, 3, 4], list[1:])
!     assert_equal([2, 3, 4], list[2:-1])
!     assert_equal([4], list[4:-1])
!     assert_equal([], list[5:-1])
!     assert_equal([], list[999:-1])
!     assert_equal([1, 2, 3, 4], list[g:theone:g:thefour])
! 
!     assert_equal([0, 1, 2, 3], list[0:3])
!     assert_equal([0], list[0:0])
!     assert_equal([0, 1, 2, 3, 4], list[0:-1])
!     assert_equal([0, 1, 2], list[0:-3])
!     assert_equal([0], list[0:-5])
!     assert_equal([], list[0:-6])
!     assert_equal([], list[0:-99])
    END
    CheckDefSuccess(lines)
    CheckScriptSuccess(['vim9script'] + lines)
--- 2822,2843 ----
      assert_equal(4, list[-1])
      assert_equal(0, list[-5])
  
!     assert_equal([0, 1, 2, 3, 4], list[0 : 4])
      assert_equal([0, 1, 2, 3, 4], list[:])
!     assert_equal([1, 2, 3, 4], list[1 :])
!     assert_equal([2, 3, 4], list[2 : -1])
!     assert_equal([4], list[4 : -1])
!     assert_equal([], list[5 : -1])
!     assert_equal([], list[999 : -1])
!     assert_equal([1, 2, 3, 4], list[g:theone : g:thefour])
! 
!     assert_equal([0, 1, 2, 3], list[0 : 3])
!     assert_equal([0], list[0 : 0])
!     assert_equal([0, 1, 2, 3, 4], list[0 : -1])
!     assert_equal([0, 1, 2], list[0 : -3])
!     assert_equal([0], list[0 : -5])
!     assert_equal([], list[0 : -6])
!     assert_equal([], list[0 : -99])
    END
    CheckDefSuccess(lines)
    CheckScriptSuccess(['vim9script'] + lines)
*** ../vim-8.2.2249/src/testdir/test_vim9_disassemble.vim       2020-12-23 
20:27:26.737538542 +0100
--- src/testdir/test_vim9_disassemble.vim       2020-12-30 20:37:00.454230666 
+0100
***************
*** 1285,1291 ****
  
  def StringSlice(): string
    var s = "abcd"
!   var res = s[1:8]
    return res
  enddef
  
--- 1285,1291 ----
  
  def StringSlice(): string
    var s = "abcd"
!   var res = s[1 : 8]
    return res
  enddef
  
***************
*** 1295,1301 ****
          'var s = "abcd"\_s*' ..
          '\d PUSHS "abcd"\_s*' ..
          '\d STORE $0\_s*' ..
!         'var res = s\[1:8]\_s*' ..
          '\d LOAD $0\_s*' ..
          '\d PUSHNR 1\_s*' ..
          '\d PUSHNR 8\_s*' ..
--- 1295,1301 ----
          'var s = "abcd"\_s*' ..
          '\d PUSHS "abcd"\_s*' ..
          '\d STORE $0\_s*' ..
!         'var res = s\[1 : 8]\_s*' ..
          '\d LOAD $0\_s*' ..
          '\d PUSHNR 1\_s*' ..
          '\d PUSHNR 8\_s*' ..
***************
*** 1331,1337 ****
  
  def ListSlice(): list<number>
    var l = [1, 2, 3]
!   var res = l[1:8]
    return res
  enddef
  
--- 1331,1337 ----
  
  def ListSlice(): list<number>
    var l = [1, 2, 3]
!   var res = l[1 : 8]
    return res
  enddef
  
***************
*** 1344,1350 ****
          '\d PUSHNR 3\_s*' ..
          '\d NEWLIST size 3\_s*' ..
          '\d STORE $0\_s*' ..
!         'var res = l\[1:8]\_s*' ..
          '\d LOAD $0\_s*' ..
          '\d PUSHNR 1\_s*' ..
          '\d PUSHNR 8\_s*' ..
--- 1344,1350 ----
          '\d PUSHNR 3\_s*' ..
          '\d NEWLIST size 3\_s*' ..
          '\d STORE $0\_s*' ..
!         'var res = l\[1 : 8]\_s*' ..
          '\d LOAD $0\_s*' ..
          '\d PUSHNR 1\_s*' ..
          '\d PUSHNR 8\_s*' ..
***************
*** 1405,1418 ****
  enddef
  
  def AnySlice(): list<number>
!   var res = g:somelist[1:3]
    return res
  enddef
  
  def Test_disassemble_any_slice()
    var instr = execute('disassemble AnySlice')
    assert_match('AnySlice\_s*' ..
!         'var res = g:somelist\[1:3\]\_s*' ..
          '\d LOADG g:somelist\_s*' ..
          '\d PUSHNR 1\_s*' ..
          '\d PUSHNR 3\_s*' ..
--- 1405,1418 ----
  enddef
  
  def AnySlice(): list<number>
!   var res = g:somelist[1 : 3]
    return res
  enddef
  
  def Test_disassemble_any_slice()
    var instr = execute('disassemble AnySlice')
    assert_match('AnySlice\_s*' ..
!         'var res = g:somelist\[1 : 3\]\_s*' ..
          '\d LOADG g:somelist\_s*' ..
          '\d PUSHNR 1\_s*' ..
          '\d PUSHNR 3\_s*' ..
*** ../vim-8.2.2249/src/version.c       2020-12-30 14:59:18.135318174 +0100
--- src/version.c       2020-12-30 20:37:26.230192976 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2250,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
51. You put a pillow case over your laptop so your lover doesn't see it while
    you are pretending to catch your breath.

 /// 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/202012301939.0BUJdmvc1019954%40masaka.moolenaar.net.

Raspunde prin e-mail lui