To: vim_dev@googlegroups.com Subject: Patch 8.2.3704 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3704 Problem: Vim9: cannot use a list declaration in a :def function. Solution: Make it work. Files: runtime/doc/vim9.txt, src/vim9compile.c, src/errors.h, src/testdir/test_vim9_assign.vim *** ../vim-8.2.3703/runtime/doc/vim9.txt 2021-10-13 15:04:28.859631740 +0100 --- runtime/doc/vim9.txt 2021-11-30 16:13:01.140854022 +0000 *************** *** 360,371 **** To ignore any remaining items: > [a, b; _] = longList - < *E1092* Declaring more than one variable at a time, using the unpack notation, is ! currently not supported: > ! var [v1, v2] = GetValues() # Error! ! That is because the type needs to be inferred from the list item type, which ! isn't that easy. Constants ~ --- 421,431 ---- To ignore any remaining items: > [a, b; _] = longList Declaring more than one variable at a time, using the unpack notation, is ! possible. Each variable can have a type or infer it from the value: > ! var [v1: number, v2] = GetValues() ! Use this only when there is a list with values, declaring one variable per ! line is much easier to read and change later. Constants ~ *** ../vim-8.2.3703/src/vim9compile.c 2021-11-29 22:02:08.108571662 +0000 --- src/vim9compile.c 2021-11-30 15:58:17.631361229 +0000 *************** *** 144,149 **** --- 144,150 ---- // any "[expr]" or ".name" char_u *lhs_dest_end; // end of the destination, including // "[expr]" or ".name". + char_u *lhs_end; // end including any type int lhs_has_index; // has "[expr]" or ".name" *************** *** 6299,6304 **** --- 6300,6306 ---- --lhs->lhs_dest_end; if (is_decl && var_end == var_start + 2 && var_end[-1] == ':') --var_end; + lhs->lhs_end = lhs->lhs_dest_end; // compute the length of the destination without "[expr]" or ".name" lhs->lhs_varlen = var_end - var_start; *************** *** 6435,6441 **** } } ! // handle "a:name" as a name, not index "name" on "a" if (lhs->lhs_varlen > 1 || var_start[lhs->lhs_varlen] != ':') var_end = lhs->lhs_dest_end; --- 6437,6443 ---- } } ! // handle "a:name" as a name, not index "name" in "a" if (lhs->lhs_varlen > 1 || var_start[lhs->lhs_varlen] != ':') var_end = lhs->lhs_dest_end; *************** *** 6456,6461 **** --- 6458,6464 ---- if (lhs->lhs_type == NULL) return FAIL; lhs->lhs_has_type = TRUE; + lhs->lhs_end = p; } else if (lhs->lhs_lvar != NULL) lhs->lhs_type = lhs->lhs_lvar->lv_type; *************** *** 6896,6908 **** if (p == NULL) return *arg == '[' ? arg : NULL; - if (var_count > 0 && is_decl) - { - // TODO: should we allow this, and figure out type inference from list - // members? - emsg(_(e_cannot_use_list_for_declaration)); - return NULL; - } lhs.lhs_name = NULL; sp = p; --- 6899,6904 ---- *************** *** 7330,7336 **** cctx->ctx_lnum = save_lnum; if (var_idx + 1 < var_count) ! var_start = skipwhite(lhs.lhs_dest_end + 1); } // For "[var, var] = expr" drop the "expr" value. --- 7326,7332 ---- cctx->ctx_lnum = save_lnum; if (var_idx + 1 < var_count) ! var_start = skipwhite(lhs.lhs_end + 1); } // For "[var, var] = expr" drop the "expr" value. *** ../vim-8.2.3703/src/errors.h 2021-11-29 10:36:15.916827518 +0000 --- src/errors.h 2021-11-30 15:36:39.680249957 +0000 *************** *** 366,373 **** INIT(= N_("E1090: Cannot assign to argument %s")); EXTERN char e_function_is_not_compiled_str[] INIT(= N_("E1091: Function is not compiled: %s")); ! EXTERN char e_cannot_use_list_for_declaration[] ! INIT(= N_("E1092: Cannot use a list for a declaration")); EXTERN char e_expected_nr_items_but_got_nr[] INIT(= N_("E1093: Expected %d items but got %d")); EXTERN char e_import_can_only_be_used_in_script[] --- 366,372 ---- INIT(= N_("E1090: Cannot assign to argument %s")); EXTERN char e_function_is_not_compiled_str[] INIT(= N_("E1091: Function is not compiled: %s")); ! // E1092 unused EXTERN char e_expected_nr_items_but_got_nr[] INIT(= N_("E1093: Expected %d items but got %d")); EXTERN char e_import_can_only_be_used_in_script[] *** ../vim-8.2.3703/src/testdir/test_vim9_assign.vim 2021-11-29 16:01:45.384711994 +0000 --- src/testdir/test_vim9_assign.vim 2021-11-30 16:09:45.301378152 +0000 *************** *** 732,738 **** assert_equal(['sdf', 'asdf', 'end'], list3) CheckDefExecFailure(['var ll = [1, 2, 3]', 'll[-4] = 6'], 'E684:') - CheckDefExecFailure(['var [v1, v2] = [1, 2]'], 'E1092:') # type becomes list var somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c'] --- 732,737 ---- *************** *** 753,758 **** --- 752,811 ---- CheckDefExecAndScriptFailure(lines, 'E1012:', 5) enddef + def Test_list_declaration() + var [v1, v2] = [1, 2] + v1 += 3 + assert_equal(4, v1) + v2 *= 3 + assert_equal(6, v2) + + var lines =<< trim END + var [v1, v2] = [1] + END + CheckDefExecAndScriptFailure2(lines, 'E1093: Expected 2 items but got 1', 'E688:') + lines =<< trim END + var testlist = [1] + var [v1, v2] = testlist + END + CheckDefExecAndScriptFailure2(lines, 'E1093: Expected 2 items but got 1', 'E688:') + lines =<< trim END + var [v1, v2] = [1, 2, 3] + END + CheckDefExecAndScriptFailure2(lines, 'E1093: Expected 2 items but got 3', 'E687:') + lines =<< trim END + var testlist = [1, 2, 3] + var [v1, v2] = testlist + END + CheckDefExecAndScriptFailure2(lines, 'E1093: Expected 2 items but got 3', 'E687:') + + var [vnr, vstr] = [123, 'text'] + vnr += 3 + assert_equal(126, vnr) + vstr ..= 'end' + assert_equal('textend', vstr) + + var [vnr2: number, vstr2: string] = [123, 'text'] + vnr2 += 3 + assert_equal(126, vnr2) + vstr2 ..= 'end' + assert_equal('textend', vstr2) + + var [vnr3: number; vlist: list] = [123, 'foo', 'bar'] + vnr3 += 5 + assert_equal(128, vnr3) + assert_equal(['foo', 'bar'], vlist) + + lines =<< trim END + var [vnr2: number, vstr2: number] = [123, 'text'] + END + CheckDefExecAndScriptFailure2(lines, 'E1163: Variable 2: type mismatch, expected number but got string', 'E1012: Type mismatch; expected number but got string') + lines =<< trim END + var testlist = [234, 'text'] + var [vnr2: number, vstr2: number] = testlist + END + CheckDefExecAndScriptFailure2(lines, 'E1163: Variable 2: type mismatch, expected number but got string', 'E1012: Type mismatch; expected number but got string') + enddef + def PartFuncBool(b: bool): string return 'done' enddef *** ../vim-8.2.3703/src/version.c 2021-11-30 13:02:55.120889114 +0000 --- src/version.c 2021-11-30 15:36:15.924291307 +0000 *************** *** 755,756 **** --- 755,758 ---- { /* Add new patch number below this line */ + /**/ + 3704, /**/ -- Why I like vim: > I like VIM because, when I ask a question in this newsgroup, I get a > one-line answer. With xemacs, I get a 1Kb lisp script with bugs in it ;-) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///