To: vim_dev@googlegroups.com Subject: Patch 8.2.2250 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 var l = [1, 2, 3] ! var res = l[1:8] return res enddef --- 1331,1337 ---- def ListSlice(): list 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 ! 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 ! 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 -- Bram@Moolenaar.net -- 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 ///