• R/O
  • SSH

vim: Commit

Mirror of the Vim source from https://github.com/vim/vim


Commit MetaInfo

Revisióndf0548b649c12d6fafa758974f105332c45848e8 (tree)
Tiempo2020-12-02 00:45:04
AutorBram Moolenaar <Bram@vim....>
CommiterBram Moolenaar

Log Message

patch 8.2.2073: Vim9: for with unpack only works for local variables

Commit: https://github.com/vim/vim/commit/4b8a065145bb53762b869cd6b8e55b7ad7341761
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Dec 1 16:30:44 2020 +0100

patch 8.2.2073: Vim9: for with unpack only works for local variables
Problem: Vim9: for with unpack only works for local variables.
Solution: Recognize different destinations.

Cambiar Resumen

Diferencia incremental

diff -r db8554aa3c92 -r df0548b649c1 src/testdir/test_vim9_script.vim
--- a/src/testdir/test_vim9_script.vim Mon Nov 30 21:45:04 2020 +0100
+++ b/src/testdir/test_vim9_script.vim Tue Dec 01 16:45:04 2020 +0100
@@ -1863,22 +1863,49 @@
18631863 enddef
18641864
18651865 def Test_for_loop_unpack()
1866- var result = []
1867- for [v1, v2] in [[1, 2], [3, 4]]
1868- result->add(v1)
1869- result->add(v2)
1870- endfor
1871- assert_equal([1, 2, 3, 4], result)
1872-
1873- result = []
1874- for [v1, v2; v3] in [[1, 2], [3, 4, 5, 6]]
1875- result->add(v1)
1876- result->add(v2)
1877- result->add(v3)
1878- endfor
1879- assert_equal([1, 2, [], 3, 4, [5, 6]], result)
1880-
18811866 var lines =<< trim END
1867+ var result = []
1868+ for [v1, v2] in [[1, 2], [3, 4]]
1869+ result->add(v1)
1870+ result->add(v2)
1871+ endfor
1872+ assert_equal([1, 2, 3, 4], result)
1873+
1874+ result = []
1875+ for [v1, v2; v3] in [[1, 2], [3, 4, 5, 6]]
1876+ result->add(v1)
1877+ result->add(v2)
1878+ result->add(v3)
1879+ endfor
1880+ assert_equal([1, 2, [], 3, 4, [5, 6]], result)
1881+
1882+ result = []
1883+ for [&ts, &sw] in [[1, 2], [3, 4]]
1884+ result->add(&ts)
1885+ result->add(&sw)
1886+ endfor
1887+ assert_equal([1, 2, 3, 4], result)
1888+
1889+ var slist: list<string>
1890+ for [$LOOPVAR, @r, v:errmsg] in [['a', 'b', 'c'], ['d', 'e', 'f']]
1891+ slist->add($LOOPVAR)
1892+ slist->add(@r)
1893+ slist->add(v:errmsg)
1894+ endfor
1895+ assert_equal(['a', 'b', 'c', 'd', 'e', 'f'], slist)
1896+
1897+ slist = []
1898+ for [g:globalvar, b:bufvar, w:winvar, t:tabvar] in [['global', 'buf', 'win', 'tab'], ['1', '2', '3', '4']]
1899+ slist->add(g:globalvar)
1900+ slist->add(b:bufvar)
1901+ slist->add(w:winvar)
1902+ slist->add(t:tabvar)
1903+ endfor
1904+ assert_equal(['global', 'buf', 'win', 'tab', '1', '2', '3', '4'], slist)
1905+ END
1906+ CheckDefAndScriptSuccess(lines)
1907+
1908+ lines =<< trim END
18821909 for [v1, v2] in [[1, 2, 3], [3, 4]]
18831910 echo v1 v2
18841911 endfor
diff -r db8554aa3c92 -r df0548b649c1 src/version.c
--- a/src/version.c Mon Nov 30 21:45:04 2020 +0100
+++ b/src/version.c Tue Dec 01 16:45:04 2020 +0100
@@ -751,6 +751,8 @@
751751 static int included_patches[] =
752752 { /* Add new patch number below this line */
753753 /**/
754+ 2073,
755+/**/
754756 2072,
755757 /**/
756758 2071,
diff -r db8554aa3c92 -r df0548b649c1 src/vim9compile.c
--- a/src/vim9compile.c Mon Nov 30 21:45:04 2020 +0100
+++ b/src/vim9compile.c Tue Dec 01 16:45:04 2020 +0100
@@ -5066,6 +5066,184 @@
50665066 }
50675067
50685068 /*
5069+ * For one assignment figure out the type of destination. Return it in "dest".
5070+ * When not recognized "dest" is not set.
5071+ * For an option "opt_flags" is set.
5072+ * For a v:var "vimvaridx" is set.
5073+ * "type" is set to the destination type if known, unchanted otherwise.
5074+ * Return FAIL if an error message was given.
5075+ */
5076+ static int
5077+get_var_dest(
5078+ char_u *name,
5079+ assign_dest_T *dest,
5080+ int cmdidx,
5081+ int *opt_flags,
5082+ int *vimvaridx,
5083+ type_T **type,
5084+ cctx_T *cctx)
5085+{
5086+ char_u *p;
5087+
5088+ if (*name == '&')
5089+ {
5090+ int cc;
5091+ long numval;
5092+ int opt_type;
5093+
5094+ *dest = dest_option;
5095+ if (cmdidx == CMD_final || cmdidx == CMD_const)
5096+ {
5097+ emsg(_(e_const_option));
5098+ return FAIL;
5099+ }
5100+ p = name;
5101+ p = find_option_end(&p, opt_flags);
5102+ if (p == NULL)
5103+ {
5104+ // cannot happen?
5105+ emsg(_(e_letunexp));
5106+ return FAIL;
5107+ }
5108+ cc = *p;
5109+ *p = NUL;
5110+ opt_type = get_option_value(skip_option_env_lead(name),
5111+ &numval, NULL, *opt_flags);
5112+ *p = cc;
5113+ if (opt_type == -3)
5114+ {
5115+ semsg(_(e_unknown_option), name);
5116+ return FAIL;
5117+ }
5118+ if (opt_type == -2 || opt_type == 0)
5119+ *type = &t_string;
5120+ else
5121+ *type = &t_number; // both number and boolean option
5122+ }
5123+ else if (*name == '$')
5124+ {
5125+ *dest = dest_env;
5126+ *type = &t_string;
5127+ }
5128+ else if (*name == '@')
5129+ {
5130+ if (!valid_yank_reg(name[1], FALSE) || name[1] == '.')
5131+ {
5132+ emsg_invreg(name[1]);
5133+ return FAIL;
5134+ }
5135+ *dest = dest_reg;
5136+ *type = &t_string;
5137+ }
5138+ else if (STRNCMP(name, "g:", 2) == 0)
5139+ {
5140+ *dest = dest_global;
5141+ }
5142+ else if (STRNCMP(name, "b:", 2) == 0)
5143+ {
5144+ *dest = dest_buffer;
5145+ }
5146+ else if (STRNCMP(name, "w:", 2) == 0)
5147+ {
5148+ *dest = dest_window;
5149+ }
5150+ else if (STRNCMP(name, "t:", 2) == 0)
5151+ {
5152+ *dest = dest_tab;
5153+ }
5154+ else if (STRNCMP(name, "v:", 2) == 0)
5155+ {
5156+ typval_T *vtv;
5157+ int di_flags;
5158+
5159+ *vimvaridx = find_vim_var(name + 2, &di_flags);
5160+ if (*vimvaridx < 0)
5161+ {
5162+ semsg(_(e_variable_not_found_str), name);
5163+ return FAIL;
5164+ }
5165+ // We use the current value of "sandbox" here, is that OK?
5166+ if (var_check_ro(di_flags, name, FALSE))
5167+ return FAIL;
5168+ *dest = dest_vimvar;
5169+ vtv = get_vim_var_tv(*vimvaridx);
5170+ *type = typval2type_vimvar(vtv, cctx->ctx_type_list);
5171+ }
5172+ return OK;
5173+}
5174+
5175+/*
5176+ * Generate a STORE instruction for "dest", not being "dest_local".
5177+ * Return FAIL when out of memory.
5178+ */
5179+ static int
5180+generate_store_var(
5181+ cctx_T *cctx,
5182+ assign_dest_T dest,
5183+ int opt_flags,
5184+ int vimvaridx,
5185+ int scriptvar_idx,
5186+ int scriptvar_sid,
5187+ type_T *type,
5188+ char_u *name)
5189+{
5190+ switch (dest)
5191+ {
5192+ case dest_option:
5193+ return generate_STOREOPT(cctx, skip_option_env_lead(name),
5194+ opt_flags);
5195+ case dest_global:
5196+ // include g: with the name, easier to execute that way
5197+ return generate_STORE(cctx, ISN_STOREG, 0, name);
5198+ case dest_buffer:
5199+ // include b: with the name, easier to execute that way
5200+ return generate_STORE(cctx, ISN_STOREB, 0, name);
5201+ case dest_window:
5202+ // include w: with the name, easier to execute that way
5203+ return generate_STORE(cctx, ISN_STOREW, 0, name);
5204+ case dest_tab:
5205+ // include t: with the name, easier to execute that way
5206+ return generate_STORE(cctx, ISN_STORET, 0, name);
5207+ case dest_env:
5208+ return generate_STORE(cctx, ISN_STOREENV, 0, name + 1);
5209+ case dest_reg:
5210+ return generate_STORE(cctx, ISN_STOREREG, name[1], NULL);
5211+ case dest_vimvar:
5212+ return generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL);
5213+ case dest_script:
5214+ if (scriptvar_idx < 0)
5215+ {
5216+ char_u *name_s = name;
5217+ int r;
5218+
5219+ // Include s: in the name for store_var()
5220+ if (name[1] != ':')
5221+ {
5222+ int len = (int)STRLEN(name) + 3;
5223+
5224+ name_s = alloc(len);
5225+ if (name_s == NULL)
5226+ name_s = name;
5227+ else
5228+ vim_snprintf((char *)name_s, len, "s:%s", name);
5229+ }
5230+ r = generate_OLDSCRIPT(cctx, ISN_STORES, name_s,
5231+ scriptvar_sid, type);
5232+ if (name_s != name)
5233+ vim_free(name_s);
5234+ return r;
5235+ }
5236+ return generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT,
5237+ scriptvar_sid, scriptvar_idx, type);
5238+ case dest_local:
5239+ case dest_expr:
5240+ // cannot happen
5241+ break;
5242+ }
5243+ return FAIL;
5244+}
5245+
5246+/*
50695247 * Compile declaration and assignment:
50705248 * "let name"
50715249 * "var name = expr"
@@ -5205,12 +5383,12 @@
52055383 var_start = arg;
52065384 for (var_idx = 0; var_idx == 0 || var_idx < var_count; var_idx++)
52075385 {
5208- char_u *var_end = skip_var_one(var_start, FALSE);
5386+ char_u *var_end;
5387+ char_u *dest_end;
52095388 size_t varlen;
52105389 int new_local = FALSE;
5211- int opt_type;
5390+ assign_dest_T dest = dest_local;
52125391 int opt_flags = 0;
5213- assign_dest_T dest = dest_local;
52145392 int vimvaridx = -1;
52155393 lvar_T *lvar = NULL;
52165394 lvar_T arg_lvar;
@@ -5218,22 +5396,27 @@
52185396 int has_index = FALSE;
52195397 int instr_count = -1;
52205398
5399+ // "dest_end" is the end of the destination, including "[expr]" or
5400+ // ".name".
5401+ // "var_end" is the end of the variable/option/etc. name.
5402+ dest_end = skip_var_one(var_start, FALSE);
52215403 if (*var_start == '@')
5222- p = var_start + 2;
5404+ var_end = var_start + 2;
52235405 else
52245406 {
52255407 // skip over the leading "&", "&l:", "&g:" and "$"
5226- p = skip_option_env_lead(var_start);
5227- p = to_name_end(p, TRUE);
5228- }
5229-
5230- // "a: type" is declaring variable "a" with a type, not "a:".
5408+ var_end = skip_option_env_lead(var_start);
5409+ var_end = to_name_end(var_end, TRUE);
5410+ }
5411+
5412+ // "a: type" is declaring variable "a" with a type, not dict "a:".
5413+ if (is_decl && dest_end == var_start + 2 && dest_end[-1] == ':')
5414+ --dest_end;
52315415 if (is_decl && var_end == var_start + 2 && var_end[-1] == ':')
52325416 --var_end;
5233- if (is_decl && p == var_start + 2 && p[-1] == ':')
5234- --p;
5235-
5236- varlen = p - var_start;
5417+
5418+ // compute the length of the destination without "[expr]" or ".name"
5419+ varlen = var_end - var_start;
52375420 vim_free(name);
52385421 name = vim_strnsave(var_start, varlen);
52395422 if (name == NULL)
@@ -5245,101 +5428,19 @@
52455428 {
52465429 int declare_error = FALSE;
52475430
5248- if (*var_start == '&')
5249- {
5250- int cc;
5251- long numval;
5252-
5253- dest = dest_option;
5254- if (cmdidx == CMD_final || cmdidx == CMD_const)
5255- {
5256- emsg(_(e_const_option));
5257- goto theend;
5258- }
5259- declare_error = is_decl;
5260- p = var_start;
5261- p = find_option_end(&p, &opt_flags);
5262- if (p == NULL)
5263- {
5264- // cannot happen?
5265- emsg(_(e_letunexp));
5266- goto theend;
5267- }
5268- cc = *p;
5269- *p = NUL;
5270- opt_type = get_option_value(skip_option_env_lead(var_start),
5271- &numval, NULL, opt_flags);
5272- *p = cc;
5273- if (opt_type == -3)
5274- {
5275- semsg(_(e_unknown_option), var_start);
5276- goto theend;
5277- }
5278- if (opt_type == -2 || opt_type == 0)
5279- type = &t_string;
5280- else
5281- type = &t_number; // both number and boolean option
5282- }
5283- else if (*var_start == '$')
5284- {
5285- dest = dest_env;
5286- type = &t_string;
5287- declare_error = is_decl;
5288- }
5289- else if (*var_start == '@')
5431+ if (get_var_dest(name, &dest, cmdidx, &opt_flags,
5432+ &vimvaridx, &type, cctx) == FAIL)
5433+ goto theend;
5434+ if (dest != dest_local)
52905435 {
5291- if (!valid_yank_reg(var_start[1], FALSE) || var_start[1] == '.')
5292- {
5293- emsg_invreg(var_start[1]);
5294- goto theend;
5295- }
5296- dest = dest_reg;
5297- type = &t_string;
5298- declare_error = is_decl;
5299- }
5300- else if (varlen > 1 && STRNCMP(var_start, "g:", 2) == 0)
5301- {
5302- dest = dest_global;
5303- declare_error = is_decl;
5304- }
5305- else if (varlen > 1 && STRNCMP(var_start, "b:", 2) == 0)
5306- {
5307- dest = dest_buffer;
5308- declare_error = is_decl;
5309- }
5310- else if (varlen > 1 && STRNCMP(var_start, "w:", 2) == 0)
5311- {
5312- dest = dest_window;
5313- declare_error = is_decl;
5314- }
5315- else if (varlen > 1 && STRNCMP(var_start, "t:", 2) == 0)
5316- {
5317- dest = dest_tab;
5318- declare_error = is_decl;
5319- }
5320- else if (varlen > 1 && STRNCMP(var_start, "v:", 2) == 0)
5321- {
5322- typval_T *vtv;
5323- int di_flags;
5324-
5325- vimvaridx = find_vim_var(name + 2, &di_flags);
5326- if (vimvaridx < 0)
5327- {
5328- semsg(_(e_variable_not_found_str), var_start);
5329- goto theend;
5330- }
5331- // We use the current value of "sandbox" here, is that OK?
5332- if (var_check_ro(di_flags, name, FALSE))
5333- goto theend;
5334- dest = dest_vimvar;
5335- vtv = get_vim_var_tv(vimvaridx);
5336- type = typval2type_vimvar(vtv, cctx->ctx_type_list);
5436+ // Specific kind of variable recognized.
53375437 declare_error = is_decl;
53385438 }
53395439 else
53405440 {
53415441 int idx;
53425442
5443+ // No specific kind of variable recognized, just a name.
53435444 for (idx = 0; reserved[idx] != NULL; ++idx)
53445445 if (STRCMP(reserved[idx], name) == 0)
53455446 {
@@ -5450,19 +5551,19 @@
54505551
54515552 // handle "a:name" as a name, not index "name" on "a"
54525553 if (varlen > 1 || var_start[varlen] != ':')
5453- p = var_end;
5554+ var_end = dest_end;
54545555
54555556 if (dest != dest_option)
54565557 {
5457- if (is_decl && *p == ':')
5558+ if (is_decl && *var_end == ':')
54585559 {
54595560 // parse optional type: "let var: type = expr"
5460- if (!VIM_ISWHITE(p[1]))
5561+ if (!VIM_ISWHITE(var_end[1]))
54615562 {
54625563 semsg(_(e_white_space_required_after_str), ":");
54635564 goto theend;
54645565 }
5465- p = skipwhite(p + 1);
5566+ p = skipwhite(var_end + 1);
54665567 type = parse_type(&p, cctx->ctx_type_list);
54675568 has_type = TRUE;
54685569 }
@@ -5499,7 +5600,7 @@
54995600 }
55005601
55015602 member_type = type;
5502- if (var_end > var_start + varlen)
5603+ if (dest_end > var_start + varlen)
55035604 {
55045605 // Something follows after the variable: "var[idx]" or "var.key".
55055606 // TODO: should we also handle "->func()" here?
@@ -5856,12 +5957,12 @@
58565957 if (type->tt_type == VAR_LIST)
58575958 {
58585959 if (generate_instr_drop(cctx, ISN_STORELIST, 3) == FAIL)
5859- return FAIL;
5960+ goto theend;
58605961 }
58615962 else if (type->tt_type == VAR_DICT)
58625963 {
58635964 if (generate_instr_drop(cctx, ISN_STOREDICT, 3) == FAIL)
5864- return FAIL;
5965+ goto theend;
58655966 }
58665967 else
58675968 {
@@ -5876,100 +5977,40 @@
58765977 // ":const var": lock the value, but not referenced variables
58775978 generate_LOCKCONST(cctx);
58785979
5879- switch (dest)
5980+ if (dest != dest_local)
58805981 {
5881- case dest_option:
5882- generate_STOREOPT(cctx, skip_option_env_lead(name),
5883- opt_flags);
5884- break;
5885- case dest_global:
5886- // include g: with the name, easier to execute that way
5887- generate_STORE(cctx, ISN_STOREG, 0, name);
5888- break;
5889- case dest_buffer:
5890- // include b: with the name, easier to execute that way
5891- generate_STORE(cctx, ISN_STOREB, 0, name);
5892- break;
5893- case dest_window:
5894- // include w: with the name, easier to execute that way
5895- generate_STORE(cctx, ISN_STOREW, 0, name);
5896- break;
5897- case dest_tab:
5898- // include t: with the name, easier to execute that way
5899- generate_STORE(cctx, ISN_STORET, 0, name);
5900- break;
5901- case dest_env:
5902- generate_STORE(cctx, ISN_STOREENV, 0, name + 1);
5903- break;
5904- case dest_reg:
5905- generate_STORE(cctx, ISN_STOREREG, name[1], NULL);
5906- break;
5907- case dest_vimvar:
5908- generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL);
5909- break;
5910- case dest_script:
5911- {
5912- if (scriptvar_idx < 0)
5913- {
5914- char_u *name_s = name;
5915-
5916- // Include s: in the name for store_var()
5917- if (name[1] != ':')
5918- {
5919- int len = (int)STRLEN(name) + 3;
5920-
5921- name_s = alloc(len);
5922- if (name_s == NULL)
5923- name_s = name;
5924- else
5925- vim_snprintf((char *)name_s, len,
5926- "s:%s", name);
5927- }
5928- generate_OLDSCRIPT(cctx, ISN_STORES, name_s,
5929- scriptvar_sid, type);
5930- if (name_s != name)
5931- vim_free(name_s);
5932- }
5933- else
5934- generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT,
5935- scriptvar_sid, scriptvar_idx, type);
5936- }
5937- break;
5938- case dest_local:
5939- if (lvar != NULL)
5940- {
5941- isn_T *isn = ((isn_T *)instr->ga_data)
5942- + instr->ga_len - 1;
5943-
5944- // optimization: turn "var = 123" from ISN_PUSHNR +
5945- // ISN_STORE into ISN_STORENR
5946- if (!lvar->lv_from_outer
5947- && instr->ga_len == instr_count + 1
5948- && isn->isn_type == ISN_PUSHNR)
5949- {
5950- varnumber_T val = isn->isn_arg.number;
5951-
5952- isn->isn_type = ISN_STORENR;
5953- isn->isn_arg.storenr.stnr_idx = lvar->lv_idx;
5954- isn->isn_arg.storenr.stnr_val = val;
5955- if (stack->ga_len > 0)
5956- --stack->ga_len;
5957- }
5958- else if (lvar->lv_from_outer)
5959- generate_STORE(cctx, ISN_STOREOUTER, lvar->lv_idx,
5960- NULL);
5961- else
5962- generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
5963- }
5964- break;
5965- case dest_expr:
5966- // cannot happen
5967- break;
5982+ if (generate_store_var(cctx, dest, opt_flags, vimvaridx,
5983+ scriptvar_idx, scriptvar_sid, type, name) == FAIL)
5984+ goto theend;
5985+ }
5986+ else if (lvar != NULL)
5987+ {
5988+ isn_T *isn = ((isn_T *)instr->ga_data)
5989+ + instr->ga_len - 1;
5990+
5991+ // optimization: turn "var = 123" from ISN_PUSHNR +
5992+ // ISN_STORE into ISN_STORENR
5993+ if (!lvar->lv_from_outer
5994+ && instr->ga_len == instr_count + 1
5995+ && isn->isn_type == ISN_PUSHNR)
5996+ {
5997+ varnumber_T val = isn->isn_arg.number;
5998+
5999+ isn->isn_type = ISN_STORENR;
6000+ isn->isn_arg.storenr.stnr_idx = lvar->lv_idx;
6001+ isn->isn_arg.storenr.stnr_val = val;
6002+ if (stack->ga_len > 0)
6003+ --stack->ga_len;
6004+ }
6005+ else if (lvar->lv_from_outer)
6006+ generate_STORE(cctx, ISN_STOREOUTER, lvar->lv_idx, NULL);
6007+ else
6008+ generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
59686009 }
59696010 }
59706011
59716012 if (var_idx + 1 < var_count)
5972- var_start = skipwhite(var_end + 1);
6013+ var_start = skipwhite(dest_end + 1);
59736014 }
59746015
59756016 // for "[var, var] = expr" drop the "expr" value
@@ -6443,6 +6484,7 @@
64436484 {
64446485 char_u *arg;
64456486 char_u *arg_end;
6487+ char_u *name = NULL;
64466488 char_u *p;
64476489 int var_count = 0;
64486490 int semicolon = FALSE;
@@ -6538,41 +6580,62 @@
65386580
65396581 for (idx = 0; idx < var_count; ++idx)
65406582 {
6541- // TODO: use skip_var_one, also assign to @r, $VAR, etc.
6542- p = arg;
6543- while (eval_isnamec(*p))
6544- ++p;
6583+ assign_dest_T dest = dest_local;
6584+ int opt_flags = 0;
6585+ int vimvaridx = -1;
6586+ type_T *type = &t_any;
6587+
6588+ p = skip_var_one(arg, FALSE);
65456589 varlen = p - arg;
6546- var_lvar = lookup_local(arg, varlen, cctx);
6547- if (var_lvar != NULL)
6548- {
6549- semsg(_(e_variable_already_declared), arg);
6550- drop_scope(cctx);
6551- return NULL;
6552- }
6553-
6554- // Reserve a variable to store "var".
6555- // TODO: check for type
6556- var_lvar = reserve_local(cctx, arg, varlen, FALSE, &t_any);
6557- if (var_lvar == NULL)
6558- {
6559- // out of memory or used as an argument
6560- drop_scope(cctx);
6561- return NULL;
6562- }
6563-
6564- if (semicolon && idx == var_count - 1)
6565- var_lvar->lv_type = vartype;
6590+ name = vim_strnsave(arg, varlen);
6591+ if (name == NULL)
6592+ goto failed;
6593+
6594+ // TODO: script var not supported?
6595+ if (get_var_dest(name, &dest, CMD_for, &opt_flags,
6596+ &vimvaridx, &type, cctx) == FAIL)
6597+ goto failed;
6598+ if (dest != dest_local)
6599+ {
6600+ if (generate_store_var(cctx, dest, opt_flags, vimvaridx,
6601+ 0, 0, type, name) == FAIL)
6602+ goto failed;
6603+ }
65666604 else
6567- var_lvar->lv_type = item_type;
6568- generate_STORE(cctx, ISN_STORE, var_lvar->lv_idx, NULL);
6605+ {
6606+ var_lvar = lookup_local(arg, varlen, cctx);
6607+ if (var_lvar != NULL)
6608+ {
6609+ semsg(_(e_variable_already_declared), arg);
6610+ goto failed;
6611+ }
6612+
6613+ // Reserve a variable to store "var".
6614+ // TODO: check for type
6615+ var_lvar = reserve_local(cctx, arg, varlen, FALSE, &t_any);
6616+ if (var_lvar == NULL)
6617+ // out of memory or used as an argument
6618+ goto failed;
6619+
6620+ if (semicolon && idx == var_count - 1)
6621+ var_lvar->lv_type = vartype;
6622+ else
6623+ var_lvar->lv_type = item_type;
6624+ generate_STORE(cctx, ISN_STORE, var_lvar->lv_idx, NULL);
6625+ }
65696626
65706627 if (*p == ',' || *p == ';')
65716628 ++p;
65726629 arg = skipwhite(p);
6630+ vim_free(name);
65736631 }
65746632
65756633 return arg_end;
6634+
6635+failed:
6636+ vim_free(name);
6637+ drop_scope(cctx);
6638+ return NULL;
65766639 }
65776640
65786641 /*
Show on old repository browser