To: vim_dev@googlegroups.com Subject: Patch 8.2.0200 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0200 Problem: Vim9 script commands not sufficiently tested. Solution: Add more tests. Fix storing global variable. Make script variables work. Files: src/vim9compile.c, src/vim9execute.c, src/vim9.h, src/evalvars.c, src/proto/evalvars.pro, src/testdir/test_vim9_script.vim, src/misc1.c, src/proto/misc1.pro *** ../vim-8.2.0199/src/vim9compile.c 2020-01-31 22:12:36.925061271 +0100 --- src/vim9compile.c 2020-02-02 22:15:19.114853233 +0100 *************** *** 335,341 **** || type2 == VAR_UNKNOWN))) { if (*op == '+') ! semsg(_("E1035: wrong argument type for +")); else semsg(_("E1036: %c requires number or float arguments"), *op); return FAIL; --- 335,341 ---- || type2 == VAR_UNKNOWN))) { if (*op == '+') ! emsg(_("E1035: wrong argument type for +")); else semsg(_("E1036: %c requires number or float arguments"), *op); return FAIL; *************** *** 721,740 **** } /* * Generate an ISN_LOADS instruction. */ static int ! generate_LOADS( cctx_T *cctx, char_u *name, ! int sid) { isn_T *isn; ! if ((isn = generate_instr_type(cctx, ISN_LOADS, &t_any)) == NULL) return FAIL; ! isn->isn_arg.loads.ls_name = vim_strsave(name); ! isn->isn_arg.loads.ls_sid = sid; return OK; } --- 721,769 ---- } /* + * Generate an ISN_LOADV instruction. + */ + static int + generate_LOADV( + cctx_T *cctx, + char_u *name, + int error) + { + // load v:var + int vidx = find_vim_var(name); + + if (vidx < 0) + { + if (error) + semsg(_(e_var_notfound), name); + return FAIL; + } + + // TODO: get actual type + return generate_LOAD(cctx, ISN_LOADV, vidx, NULL, &t_any); + } + + /* * Generate an ISN_LOADS instruction. */ static int ! generate_OLDSCRIPT( cctx_T *cctx, + isntype_T isn_type, char_u *name, ! int sid, ! type_T *type) { isn_T *isn; ! if (isn_type == ISN_LOADS) ! isn = generate_instr_type(cctx, isn_type, type); ! else ! isn = generate_instr_drop(cctx, isn_type, 1); ! if (isn == NULL) return FAIL; ! isn->isn_arg.loadstore.ls_name = vim_strsave(name); ! isn->isn_arg.loadstore.ls_sid = sid; return OK; } *************** *** 743,749 **** * Generate an ISN_LOADSCRIPT or ISN_STORESCRIPT instruction. */ static int ! generate_SCRIPT( cctx_T *cctx, isntype_T isn_type, int sid, --- 772,778 ---- * Generate an ISN_LOADSCRIPT or ISN_STORESCRIPT instruction. */ static int ! generate_VIM9SCRIPT( cctx_T *cctx, isntype_T isn_type, int sid, *************** *** 1476,1488 **** if (idx == -1) { // variable exists but is not in sn_var_vals: old style script. ! return generate_LOADS(cctx, name, current_sctx.sc_sid); } if (idx >= 0) { svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx; ! generate_SCRIPT(cctx, ISN_LOADSCRIPT, current_sctx.sc_sid, idx, sv->sv_type); return OK; } --- 1505,1518 ---- if (idx == -1) { // variable exists but is not in sn_var_vals: old style script. ! return generate_OLDSCRIPT(cctx, ISN_LOADS, name, current_sctx.sc_sid, ! &t_any); } if (idx >= 0) { svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx; ! generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT, current_sctx.sc_sid, idx, sv->sv_type); return OK; } *************** *** 1491,1497 **** if (import != NULL) { // TODO: check this is a variable, not a function ! generate_SCRIPT(cctx, ISN_LOADSCRIPT, import->imp_sid, import->imp_var_vals_idx, import->imp_type); --- 1521,1527 ---- if (import != NULL) { // TODO: check this is a variable, not a function ! generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT, import->imp_sid, import->imp_var_vals_idx, import->imp_type); *************** *** 1523,1540 **** if (**arg == 'v') { ! // load v:var ! int vidx = find_vim_var(name); ! ! if (vidx < 0) ! { ! if (error) ! semsg(_(e_var_notfound), name); ! goto theend; ! } ! ! // TODO: get actual type ! res = generate_LOAD(cctx, ISN_LOADV, vidx, NULL, &t_any); } else if (**arg == 'g') { --- 1553,1559 ---- if (**arg == 'v') { ! res = generate_LOADV(cctx, name, error); } else if (**arg == 'g') { *************** *** 3071,3076 **** --- 3090,3098 ---- int opt_type; int opt_flags = 0; int global = FALSE; + int env = FALSE; + int reg = FALSE; + int vimvaridx = -1; int script = FALSE; int oplen = 0; int heredoc = FALSE; *************** *** 3135,3140 **** --- 3157,3185 ---- else type = &t_number; // both number and boolean option } + else if (*arg == '$') + { + env = TRUE; + if (is_decl) + { + semsg(_("E1065: Cannot declare an environment variable: %s"), name); + goto theend; + } + } + else if (*arg == '@') + { + if (!valid_yank_reg(arg[1], TRUE)) + { + emsg_invreg(arg[1]); + return FAIL; + } + reg = TRUE; + if (is_decl) + { + semsg(_("E1066: Cannot declare a register: %s"), name); + goto theend; + } + } else if (STRNCMP(arg, "g:", 2) == 0) { global = TRUE; *************** *** 3144,3149 **** --- 3189,3208 ---- goto theend; } } + else if (STRNCMP(arg, "v:", 2) == 0) + { + vimvaridx = find_vim_var(name + 2); + if (vimvaridx < 0) + { + semsg(_(e_var_notfound), arg); + goto theend; + } + if (is_decl) + { + semsg(_("E1064: Cannot declare a v: variable: %s"), name); + goto theend; + } + } else { for (idx = 0; reserved[idx] != NULL; ++idx) *************** *** 3171,3177 **** } } } ! else if (lookup_script(arg, varlen) == OK) { script = TRUE; if (is_decl) --- 3230,3238 ---- } } } ! else if ((STRNCMP(arg, "s:", 2) == 0 ! ? lookup_script(arg + 2, varlen - 2) ! : lookup_script(arg, varlen)) == OK) { script = TRUE; if (is_decl) *************** *** 3226,3232 **** } // +=, /=, etc. require an existing variable ! if (idx < 0 && !global && !option) { if (oplen > 1 && !heredoc) { --- 3287,3293 ---- } // +=, /=, etc. require an existing variable ! if (idx < 0 && !global && !env && !reg && !option) { if (oplen > 1 && !heredoc) { *************** *** 3272,3277 **** --- 3333,3345 ---- generate_LOAD(cctx, ISN_LOADOPT, 0, name + 1, type); else if (global) generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type); + else if (env) + // Include $ in the name here + generate_LOAD(cctx, ISN_LOADENV, 0, name, type); + else if (reg) + generate_LOAD(cctx, ISN_LOADREG, arg[1], NULL, &t_string); + else if (vimvaridx >= 0) + generate_LOADV(cctx, name + 2, TRUE); else generate_LOAD(cctx, ISN_LOAD, idx, NULL, type); } *************** *** 3362,3373 **** if (option) generate_STOREOPT(cctx, name + 1, opt_flags); else if (global) ! generate_STORE(cctx, ISN_STOREG, 0, name + 2); else if (script) { ! idx = get_script_item_idx(current_sctx.sc_sid, name, TRUE); // TODO: specific type ! generate_SCRIPT(cctx, ISN_STORESCRIPT, current_sctx.sc_sid, idx, &t_any); } else --- 3430,3454 ---- if (option) generate_STOREOPT(cctx, name + 1, opt_flags); else if (global) ! // include g: with the name, easier to execute that way ! generate_STORE(cctx, ISN_STOREG, 0, name); ! else if (env) ! generate_STORE(cctx, ISN_STOREENV, 0, name + 1); ! else if (reg) ! generate_STORE(cctx, ISN_STOREREG, name[1], NULL); ! else if (vimvaridx >= 0) ! generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL); else if (script) { ! char_u *rawname = name + (name[1] == ':' ? 2 : 0); ! ! idx = get_script_item_idx(current_sctx.sc_sid, rawname, TRUE); // TODO: specific type ! if (idx < 0) ! generate_OLDSCRIPT(cctx, ISN_STORES, rawname, ! current_sctx.sc_sid, &t_any); ! else ! generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT, current_sctx.sc_sid, idx, &t_any); } else *************** *** 4527,4534 **** ea.cmd = skipwhite(ea.cmd); // Assuming the command starts with a variable or function name, find ! // what follows. Also "&opt = value". ! p = (*ea.cmd == '&') ? ea.cmd + 1 : ea.cmd; p = to_name_end(p); if (p > ea.cmd && *p != NUL) { --- 4608,4616 ---- ea.cmd = skipwhite(ea.cmd); // Assuming the command starts with a variable or function name, find ! // what follows. Also "&opt = val", "$ENV = val" and "@r = val". ! p = (*ea.cmd == '&' || *ea.cmd == '$' || *ea.cmd == '@') ! ? ea.cmd + 1 : ea.cmd; p = to_name_end(p); if (p > ea.cmd && *p != NUL) { *************** *** 4554,4560 **** --- 4636,4646 ---- // "g:var = expr" // "var = expr" where "var" is a local var name. // "&opt = expr" + // "$ENV = expr" + // "@r = expr" if (*ea.cmd == '&' + || *ea.cmd == '$' + || *ea.cmd == '@' || ((p - ea.cmd) > 2 && ea.cmd[1] == ':') || lookup_local(ea.cmd, p - ea.cmd, &cctx) >= 0 || lookup_script(ea.cmd, p - ea.cmd) == OK) *************** *** 4776,4787 **** case ISN_MEMBER: case ISN_PUSHEXC: case ISN_PUSHS: case ISN_STOREG: vim_free(isn->isn_arg.string); break; case ISN_LOADS: ! vim_free(isn->isn_arg.loads.ls_name); break; case ISN_STOREOPT: --- 4862,4875 ---- case ISN_MEMBER: case ISN_PUSHEXC: case ISN_PUSHS: + case ISN_STOREENV: case ISN_STOREG: vim_free(isn->isn_arg.string); break; case ISN_LOADS: ! case ISN_STORES: ! vim_free(isn->isn_arg.loadstore.ls_name); break; case ISN_STOREOPT: *************** *** 4841,4847 **** --- 4929,4937 ---- case ISN_PUSHSPEC: case ISN_RETURN: case ISN_STORE: + case ISN_STOREV: case ISN_STORENR: + case ISN_STOREREG: case ISN_STORESCRIPT: case ISN_THROW: case ISN_TRY: *** ../vim-8.2.0199/src/vim9execute.c 2020-02-02 17:22:23.438043236 +0100 --- src/vim9execute.c 2020-02-02 22:15:29.226813170 +0100 *************** *** 488,494 **** ++ectx.ec_stack.ga_len; break; ! // load s: variable in vim9script case ISN_LOADSCRIPT: { scriptitem_T *si = --- 488,494 ---- ++ectx.ec_stack.ga_len; break; ! // load s: variable in Vim9 script case ISN_LOADSCRIPT: { scriptitem_T *si = *************** *** 507,518 **** // load s: variable in old script case ISN_LOADS: { ! hashtab_T *ht = &SCRIPT_VARS(iptr->isn_arg.loads.ls_sid); ! char_u *name = iptr->isn_arg.loads.ls_name; dictitem_T *di = find_var_in_ht(ht, 0, name, TRUE); if (di == NULL) { ! semsg(_("E121: Undefined variable: s:%s"), name); goto failed; } else --- 507,519 ---- // load s: variable in old script case ISN_LOADS: { ! hashtab_T *ht = &SCRIPT_VARS( ! iptr->isn_arg.loadstore.ls_sid); ! char_u *name = iptr->isn_arg.loadstore.ls_name; dictitem_T *di = find_var_in_ht(ht, 0, name, TRUE); if (di == NULL) { ! semsg(_(e_undefvar), name); goto failed; } else *************** *** 601,607 **** *tv = *STACK_TV_BOT(0); break; ! // store script-local variable case ISN_STORESCRIPT: { scriptitem_T *si = SCRIPT_ITEM( --- 602,627 ---- *tv = *STACK_TV_BOT(0); break; ! // store s: variable in old script ! case ISN_STORES: ! { ! hashtab_T *ht = &SCRIPT_VARS( ! iptr->isn_arg.loadstore.ls_sid); ! char_u *name = iptr->isn_arg.loadstore.ls_name; ! dictitem_T *di = find_var_in_ht(ht, 0, name, TRUE); ! ! if (di == NULL) ! { ! semsg(_(e_undefvar), name); ! goto failed; ! } ! --ectx.ec_stack.ga_len; ! clear_tv(&di->di_tv); ! di->di_tv = *STACK_TV_BOT(0); ! } ! break; ! ! // store script-local variable in Vim9 script case ISN_STORESCRIPT: { scriptitem_T *si = SCRIPT_ITEM( *************** *** 648,653 **** --- 668,699 ---- } break; + // store $ENV + case ISN_STOREENV: + --ectx.ec_stack.ga_len; + vim_setenv_ext(iptr->isn_arg.string, + tv_get_string(STACK_TV_BOT(0))); + break; + + // store @r + case ISN_STOREREG: + { + int reg = iptr->isn_arg.number; + + --ectx.ec_stack.ga_len; + write_reg_contents(reg == '@' ? '"' : reg, + tv_get_string(STACK_TV_BOT(0)), -1, FALSE); + } + break; + + // store v: variable + case ISN_STOREV: + --ectx.ec_stack.ga_len; + if (set_vim_var_tv(iptr->isn_arg.number, STACK_TV_BOT(0)) + == FAIL) + goto failed; + break; + // store g: variable case ISN_STOREG: { *************** *** 1583,1589 **** break; case ISN_LOADS: { ! scriptitem_T *si = SCRIPT_ITEM(iptr->isn_arg.loads.ls_sid); smsg("%4d LOADS s:%s from %s", current, iptr->isn_arg.string, si->sn_name); --- 1629,1636 ---- break; case ISN_LOADS: { ! scriptitem_T *si = SCRIPT_ITEM( ! iptr->isn_arg.loadstore.ls_sid); smsg("%4d LOADS s:%s from %s", current, iptr->isn_arg.string, si->sn_name); *************** *** 1605,1612 **** case ISN_STORE: smsg("%4d STORE $%lld", current, iptr->isn_arg.number); break; case ISN_STOREG: ! smsg("%4d STOREG g:%s", current, iptr->isn_arg.string); break; case ISN_STORESCRIPT: { --- 1652,1672 ---- case ISN_STORE: smsg("%4d STORE $%lld", current, iptr->isn_arg.number); break; + case ISN_STOREV: + smsg("%4d STOREV v:%s", current, + get_vim_var_name(iptr->isn_arg.number)); + break; case ISN_STOREG: ! smsg("%4d STOREG %s", current, iptr->isn_arg.string); ! break; ! case ISN_STORES: ! { ! scriptitem_T *si = SCRIPT_ITEM( ! iptr->isn_arg.loadstore.ls_sid); ! ! smsg("%4d STORES s:%s in %s", current, ! iptr->isn_arg.string, si->sn_name); ! } break; case ISN_STORESCRIPT: { *************** *** 1623,1629 **** smsg("%4d STOREOPT &%s", current, iptr->isn_arg.storeopt.so_name); break; ! case ISN_STORENR: smsg("%4d STORE %lld in $%d", current, iptr->isn_arg.storenr.str_val, --- 1683,1694 ---- smsg("%4d STOREOPT &%s", current, iptr->isn_arg.storeopt.so_name); break; ! case ISN_STOREENV: ! smsg("%4d STOREENV $%s", current, iptr->isn_arg.string); ! break; ! case ISN_STOREREG: ! smsg("%4d STOREREG @%c", current, iptr->isn_arg.number); ! break; case ISN_STORENR: smsg("%4d STORE %lld in $%d", current, iptr->isn_arg.storenr.str_val, *** ../vim-8.2.0199/src/vim9.h 2020-01-26 15:52:33.027833222 +0100 --- src/vim9.h 2020-02-02 22:11:13.775829855 +0100 *************** *** 18,34 **** // get and set variables ISN_LOAD, // push local variable isn_arg.number ISN_LOADV, // push v: variable isn_arg.number - ISN_LOADSCRIPT, // push script-local variable isn_arg.script. - ISN_LOADS, // push s: variable isn_arg.string ISN_LOADG, // push g: variable isn_arg.string ISN_LOADOPT, // push option isn_arg.string ISN_LOADENV, // push environment variable isn_arg.string ISN_LOADREG, // push register isn_arg.number ISN_STORE, // pop into local variable isn_arg.number ISN_STOREG, // pop into global variable isn_arg.string ISN_STORESCRIPT, // pop into scirpt variable isn_arg.script ISN_STOREOPT, // pop into option isn_arg.string // ISN_STOREOTHER, // pop into other script variable isn_arg.other. ISN_STORENR, // store number into local variable isn_arg.storenr.str_idx --- 18,38 ---- // get and set variables ISN_LOAD, // push local variable isn_arg.number ISN_LOADV, // push v: variable isn_arg.number ISN_LOADG, // push g: variable isn_arg.string + ISN_LOADS, // push s: variable isn_arg.loadstore + ISN_LOADSCRIPT, // push script-local variable isn_arg.script. ISN_LOADOPT, // push option isn_arg.string ISN_LOADENV, // push environment variable isn_arg.string ISN_LOADREG, // push register isn_arg.number ISN_STORE, // pop into local variable isn_arg.number + ISN_STOREV, // pop into v: variable isn_arg.number ISN_STOREG, // pop into global variable isn_arg.string + ISN_STORES, // pop into scirpt variable isn_arg.loadstore ISN_STORESCRIPT, // pop into scirpt variable isn_arg.script ISN_STOREOPT, // pop into option isn_arg.string + ISN_STOREENV, // pop into environment variable isn_arg.string + ISN_STOREREG, // pop into register isn_arg.number // ISN_STOREOTHER, // pop into other script variable isn_arg.other. ISN_STORENR, // store number into local variable isn_arg.storenr.str_idx *************** *** 180,192 **** int so_flags; } storeopt_T; ! // arguments to ISN_LOADS typedef struct { char_u *ls_name; // variable name int ls_sid; // script ID ! } loads_T; ! // arguments to ISN_LOADSCRIPT typedef struct { int script_sid; // script ID int script_idx; // index in sn_var_vals --- 184,196 ---- int so_flags; } storeopt_T; ! // arguments to ISN_LOADS and ISN_STORES typedef struct { char_u *ls_name; // variable name int ls_sid; // script ID ! } loadstore_T; ! // arguments to ISN_LOADSCRIPT and ISN_STORESCRIPT typedef struct { int script_sid; // script ID int script_idx; // index in sn_var_vals *************** *** 217,223 **** checktype_T type; storenr_T storenr; storeopt_T storeopt; ! loads_T loads; script_T script; } isn_arg; } isn_T; --- 221,227 ---- checktype_T type; storenr_T storenr; storeopt_T storeopt; ! loadstore_T loadstore; script_T script; } isn_arg; } isn_T; *** ../vim-8.2.0199/src/evalvars.c 2020-01-29 21:27:17.574406732 +0100 --- src/evalvars.c 2020-02-02 21:53:08.656448968 +0100 *************** *** 1206,1219 **** } if (p != NULL) { ! vim_setenv(name, p); ! if (STRICMP(name, "HOME") == 0) ! init_homedir(); ! else if (didset_vim && STRICMP(name, "VIM") == 0) ! didset_vim = FALSE; ! else if (didset_vimruntime ! && STRICMP(name, "VIMRUNTIME") == 0) ! didset_vimruntime = FALSE; arg_end = arg; } name[len] = c1; --- 1206,1212 ---- } if (p != NULL) { ! vim_setenv_ext(name, p); arg_end = arg; } name[len] = c1; *************** *** 1967,1972 **** --- 1960,1983 ---- } /* + * Set v: variable to "tv". Only accepts the same type. + * Takes over the value of "tv". + */ + int + set_vim_var_tv(int idx, typval_T *tv) + { + if (vimvars[idx].vv_type != tv->v_type) + { + emsg(_("E1063: type mismatch for v: variable")); + clear_tv(tv); + return FAIL; + } + clear_tv(&vimvars[idx].vv_di.di_tv); + vimvars[idx].vv_di.di_tv = *tv; + return OK; + } + + /* * Get number v: variable value. */ varnumber_T *** ../vim-8.2.0199/src/proto/evalvars.pro 2020-01-26 15:52:33.023833239 +0100 --- src/proto/evalvars.pro 2020-02-02 19:19:18.086361229 +0100 *************** *** 33,38 **** --- 33,39 ---- void set_vim_var_nr(int idx, varnumber_T val); char *get_vim_var_name(int idx); typval_T *get_vim_var_tv(int idx); + int set_vim_var_tv(int idx, typval_T *tv); varnumber_T get_vim_var_nr(int idx); char_u *get_vim_var_str(int idx); list_T *get_vim_var_list(int idx); *** ../vim-8.2.0199/src/testdir/test_vim9_script.vim 2020-02-02 17:22:23.438043236 +0100 --- src/testdir/test_vim9_script.vim 2020-02-02 22:19:47.709797087 +0100 *************** *** 42,47 **** --- 42,54 ---- let dict1: dict = #{key: 'value'} let dict2: dict = #{one: 1, two: 2} + + v:char = 'abc' + call assert_equal('abc', v:char) + + $ENVVAR = 'foobar' + call assert_equal('foobar', $ENVVAR) + $ENVVAR = '' enddef func Test_assignment_failure() *************** *** 106,112 **** Increment() " works with and without :call assert_equal(4, g:counter) ! assert_equal(4, g:counter) unlet g:counter enddef --- 113,119 ---- Increment() " works with and without :call assert_equal(4, g:counter) ! call assert_equal(4, g:counter) unlet g:counter enddef *************** *** 311,317 **** let import_lines = [ \ 'vim9script', \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"', ! \ 'g:imported_abs = exported', \ ] writefile(import_lines, 'Ximport_abs.vim') writefile(s:export_script_lines, 'Xexport_abs.vim') --- 318,328 ---- let import_lines = [ \ 'vim9script', \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"', ! \ 'def UseExported()', ! \ ' g:imported_abs = exported', ! \ 'enddef', ! \ 'UseExported()', ! \ 'g:import_disassabled = execute("disass UseExported")', \ ] writefile(import_lines, 'Ximport_abs.vim') writefile(s:export_script_lines, 'Xexport_abs.vim') *************** *** 319,325 **** --- 330,341 ---- source Ximport_abs.vim assert_equal(9876, g:imported_abs) + assert_match('\d\+_UseExported.*' + \ .. 'g:imported_abs = exported.*' + \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*' + \ .. '1 STOREG g:imported_abs', g:import_disassabled) unlet g:imported_abs + unlet g:import_disassabled delete('Ximport_abs.vim') delete('Xexport_abs.vim') *************** *** 405,411 **** let s:scriptvar = 4 let g:globalvar = 'g' ! def s:ScriptFunc(arg: string) let local = 1 buffers echo arg --- 421,427 ---- let s:scriptvar = 4 let g:globalvar = 'g' ! def s:ScriptFuncLoad(arg: string) let local = 1 buffers echo arg *************** *** 418,429 **** echo @z enddef def Test_disassemble() assert_fails('disass NoFunc', 'E1061:') assert_fails('disass NotCompiled', 'E1062:') ! let res = execute('disass s:ScriptFunc') ! assert_match('\d*_ScriptFunc.*' \ .. 'buffers.*' \ .. ' EXEC \+buffers.*' \ .. ' LOAD arg\[-1\].*' --- 434,458 ---- echo @z enddef + def s:ScriptFuncStore() + let localnr = 1 + localnr = 2 + let localstr = 'abc' + localstr = 'xyz' + v:char = 'abc' + s:scriptvar = 'sv' + g:globalvar = 'gv' + &tabstop = 8 + $ENVVAR = 'ev' + @z = 'rv' + enddef + def Test_disassemble() assert_fails('disass NoFunc', 'E1061:') assert_fails('disass NotCompiled', 'E1062:') ! let res = execute('disass s:ScriptFuncLoad') ! assert_match('\d*_ScriptFuncLoad.*' \ .. 'buffers.*' \ .. ' EXEC \+buffers.*' \ .. ' LOAD arg\[-1\].*' *************** *** 432,438 **** \ .. ' LOADS s:scriptvar from .*test_vim9_script.vim.*' \ .. ' LOADG g:globalvar.*' \ .. ' LOADENV $ENVVAR.*' ! \ .. ' LOADREG @z.*', res) enddef --- 461,491 ---- \ .. ' LOADS s:scriptvar from .*test_vim9_script.vim.*' \ .. ' LOADG g:globalvar.*' \ .. ' LOADENV $ENVVAR.*' ! \ .. ' LOADREG @z.*' ! \, res) ! ! " TODO: ! " v:char = ! " s:scriptvar = ! res = execute('disass s:ScriptFuncStore') ! assert_match('\d*_ScriptFuncStore.*' ! \ .. 'localnr = 2.*' ! \ .. ' STORE 2 in $0.*' ! \ .. 'localstr = ''xyz''.*' ! \ .. ' STORE $1.*' ! \ .. 'v:char = ''abc''.*' ! \ .. 'STOREV v:char.*' ! \ .. 's:scriptvar = ''sv''.*' ! \ .. ' STORES s:scriptvar in .*test_vim9_script.vim.*' ! \ .. 'g:globalvar = ''gv''.*' ! \ .. ' STOREG g:globalvar.*' ! \ .. '&tabstop = 8.*' ! \ .. ' STOREOPT &tabstop.*' ! \ .. '$ENVVAR = ''ev''.*' ! \ .. ' STOREENV $ENVVAR.*' ! \ .. '@z = ''rv''.*' ! \ .. ' STOREREG @z.*' ! \, res) enddef *** ../vim-8.2.0199/src/misc1.c 2020-01-26 15:52:33.023833239 +0100 --- src/misc1.c 2020-02-02 21:54:12.984146020 +0100 *************** *** 1854,1859 **** --- 1854,1875 ---- /* + * Set environment variable "name" and take care of side effects. + */ + void + vim_setenv_ext(char_u *name, char_u *val) + { + vim_setenv(name, val); + if (STRICMP(name, "HOME") == 0) + init_homedir(); + else if (didset_vim && STRICMP(name, "VIM") == 0) + didset_vim = FALSE; + else if (didset_vimruntime + && STRICMP(name, "VIMRUNTIME") == 0) + didset_vimruntime = FALSE; + } + + /* * Our portable version of setenv. */ void *** ../vim-8.2.0199/src/proto/misc1.pro 2019-12-12 12:55:27.000000000 +0100 --- src/proto/misc1.pro 2020-02-02 21:54:28.140075565 +0100 *************** *** 31,36 **** --- 31,37 ---- void expand_env_esc(char_u *srcp, char_u *dst, int dstlen, int esc, int one, char_u *startstr); char_u *vim_getenv(char_u *name, int *mustfree); void vim_unsetenv(char_u *var); + void vim_setenv_ext(char_u *name, char_u *val); void vim_setenv(char_u *name, char_u *val); char_u *get_env_name(expand_T *xp, int idx); char_u *get_users(expand_T *xp, int idx); *** ../vim-8.2.0199/src/version.c 2020-02-02 17:22:23.438043236 +0100 --- src/version.c 2020-02-02 22:22:01.497284794 +0100 *************** *** 744,745 **** --- 744,747 ---- { /* Add new patch number below this line */ + /**/ + 200, /**/ -- How To Keep A Healthy Level Of Insanity: 7. Finish all your sentences with "in accordance with the prophecy". /// 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 ///