Patch 8.2.0600
Problem: Vim9: cannot read or write w:, t: and b: variables.
Solution: Implement load and store for w:, t: and b: variables.
(closes #5950)
Files: src/testdir/test_vim9_disassemble.vim,
src/testdir/test_vim9_expr.vim, src/testdir/test_vim9_script.vim,
src/vim9.h, src/vim9compile.c, src/vim9execute.c
*** ../vim-8.2.0599/src/testdir/test_vim9_disassemble.vim 2020-04-18
19:53:24.535912281 +0200
--- src/testdir/test_vim9_disassemble.vim 2020-04-19 14:19:23.685767255
+0200
***************
*** 8,13 ****
--- 8,16 ----
let s:scriptvar = 4
let g:globalvar = 'g'
+ let b:buffervar = 'b'
+ let w:windowvar = 'w'
+ let t:tabpagevar = 't'
def s:ScriptFuncLoad(arg: string)
let local = 1
***************
*** 17,22 ****
--- 20,28 ----
echo v:version
echo s:scriptvar
echo g:globalvar
+ echo b:buffervar
+ echo w:windowvar
+ echo t:tabpagevar
echo &tabstop
echo $ENVVAR
echo @z
***************
*** 39,44 ****
--- 45,53 ----
' LOADV v:version.*' ..
' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*' ..
' LOADG g:globalvar.*' ..
+ ' LOADB b:buffervar.*' ..
+ ' LOADW w:windowvar.*' ..
+ ' LOADT t:tabpagevar.*' ..
' LOADENV $ENVVAR.*' ..
' LOADREG @z.*',
res)
***************
*** 79,84 ****
--- 88,96 ----
v:char = 'abc'
s:scriptvar = 'sv'
g:globalvar = 'gv'
+ b:buffervar = 'bv'
+ w:windowvar = 'wv'
+ t:tabpagevar = 'tv'
&tabstop = 8
$ENVVAR = 'ev'
@z = 'rv'
***************
*** 99,104 ****
--- 111,122 ----
' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
'g:globalvar = ''gv''.*' ..
' STOREG g:globalvar.*' ..
+ 'b:buffervar = ''bv''.*' ..
+ ' STOREB b:buffervar.*' ..
+ 'w:windowvar = ''wv''.*' ..
+ ' STOREW w:windowvar.*' ..
+ 't:tabpagevar = ''tv''.*' ..
+ ' STORET t:tabpagevar.*' ..
'&tabstop = 8.*' ..
' STOREOPT &tabstop.*' ..
'$ENVVAR = ''ev''.*' ..
*** ../vim-8.2.0599/src/testdir/test_vim9_expr.vim 2020-04-13
17:20:56.174130307 +0200
--- src/testdir/test_vim9_expr.vim 2020-04-19 14:19:23.685767255 +0200
***************
*** 931,941 ****
call CheckDefFailure("echo l:somevar", 'E1075:')
call CheckDefFailure("echo x:somevar", 'E1075:')
- " TODO
- call CheckDefFailure("echo b:somevar", 'not supported yet')
- call CheckDefFailure("echo w:somevar", 'not supported yet')
- call CheckDefFailure("echo t:somevar", 'not supported yet')
-
call CheckDefExecFailure("let x = +g:astring", 'E1030:')
call CheckDefExecFailure("let x = +g:ablob", 'E974:')
call CheckDefExecFailure("let x = +g:alist", 'E745:')
--- 931,936 ----
*** ../vim-8.2.0599/src/testdir/test_vim9_script.vim 2020-04-18
19:53:24.535912281 +0200
--- src/testdir/test_vim9_script.vim 2020-04-19 14:30:18.184264079 +0200
***************
*** 135,140 ****
--- 135,172 ----
call CheckDefFailure(['v:errmsg += 123'], 'E1013:')
enddef
+ def Test_assignment_local()
+ " Test in a separated file in order not to the current buffer/window/tab is
+ " changed.
+ let script_lines: list<string> =<< trim END
+ let b:existing = 'yes'
+ let w:existing = 'yes'
+ let t:existing = 'yes'
+
+ def Test_assignment_local_internal()
+ b:newvar = 'new'
+ assert_equal('new', b:newvar)
+ assert_equal('yes', b:existing)
+ b:existing = 'no'
+ assert_equal('no', b:existing)
+
+ w:newvar = 'new'
+ assert_equal('new', w:newvar)
+ assert_equal('yes', w:existing)
+ w:existing = 'no'
+ assert_equal('no', w:existing)
+
+ t:newvar = 'new'
+ assert_equal('new', t:newvar)
+ assert_equal('yes', t:existing)
+ t:existing = 'no'
+ assert_equal('no', t:existing)
+ enddef
+ call Test_assignment_local_internal()
+ END
+ call CheckScriptSuccess(script_lines)
+ enddef
+
def Test_assignment_default()
# Test default values.
***************
*** 201,211 ****
--- 233,249 ----
call CheckDefFailure(['let @a = 5'], 'E1066:')
call CheckDefFailure(['let g:var = 5'], 'E1016:')
+ call CheckDefFailure(['let w:var = 5'], 'E1079:')
+ call CheckDefFailure(['let b:var = 5'], 'E1078:')
+ call CheckDefFailure(['let t:var = 5'], 'E1080:')
call CheckDefFailure(['let anr = 4', 'anr ..= "text"'], 'E1019:')
call CheckDefFailure(['let xnr += 4'], 'E1020:')
call CheckScriptFailure(['vim9script', 'def Func()', 'let dummy =
s:notfound', 'enddef'], 'E1050:')
+ " TODO: implement this error
+ "call CheckScriptFailure(['vim9script', 'let svar = 123', 'unlet svar'],
'E1050:')
+ "call CheckScriptFailure(['vim9script', 'let svar = 123', 'unlet s:svar'],
'E1050:')
call CheckDefFailure(['let var: list<string> = [123]'], 'expected
list<string> but got list<number>')
call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected
list<number> but got list<string>')
*** ../vim-8.2.0599/src/vim9.h 2020-04-09 21:08:06.298505479 +0200
--- src/vim9.h 2020-04-19 14:19:23.685767255 +0200
***************
*** 20,25 ****
--- 20,28 ----
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_LOADB, // push b: variable isn_arg.string
+ ISN_LOADW, // push w: variable isn_arg.string
+ ISN_LOADT, // push t: 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
***************
*** 29,34 ****
--- 32,40 ----
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_STOREB, // pop into buffer-local variable isn_arg.string
+ ISN_STOREW, // pop into window-local variable isn_arg.string
+ ISN_STORET, // pop into tab-local variable isn_arg.string
ISN_STORES, // pop into script variable isn_arg.loadstore
ISN_STORESCRIPT, // pop into script variable isn_arg.script
ISN_STOREOPT, // pop into option isn_arg.string
*** ../vim-8.2.0599/src/vim9compile.c 2020-04-18 19:53:24.531912284 +0200
--- src/vim9compile.c 2020-04-19 14:19:23.685767255 +0200
***************
*** 2235,2252 ****
}
else if (**arg == 'b')
{
! semsg("Namespace b: not supported yet: %s", *arg);
! goto theend;
}
else if (**arg == 'w')
{
! semsg("Namespace w: not supported yet: %s", *arg);
! goto theend;
}
else if (**arg == 't')
{
! semsg("Namespace t: not supported yet: %s", *arg);
! goto theend;
}
else
{
--- 2235,2255 ----
}
else if (**arg == 'b')
{
! // Buffer-local variables can be defined later, thus we don't check
! // if it exists, give error at runtime.
! res = generate_LOAD(cctx, ISN_LOADB, 0, name, &t_any);
}
else if (**arg == 'w')
{
! // Window-local variables can be defined later, thus we don't check
! // if it exists, give error at runtime.
! res = generate_LOAD(cctx, ISN_LOADW, 0, name, &t_any);
}
else if (**arg == 't')
{
! // Tabpage-local variables can be defined later, thus we don't
! // check if it exists, give error at runtime.
! res = generate_LOAD(cctx, ISN_LOADT, 0, name, &t_any);
}
else
{
***************
*** 3958,3963 ****
--- 3961,3969 ----
dest_option,
dest_env,
dest_global,
+ dest_buffer,
+ dest_window,
+ dest_tab,
dest_vimvar,
dest_script,
dest_reg,
***************
*** 4087,4092 ****
--- 4093,4125 ----
goto theend;
}
}
+ else if (STRNCMP(arg, "b:", 2) == 0)
+ {
+ dest = dest_buffer;
+ if (is_decl)
+ {
+ semsg(_("E1078: Cannot declare a buffer variable: %s"), name);
+ goto theend;
+ }
+ }
+ else if (STRNCMP(arg, "w:", 2) == 0)
+ {
+ dest = dest_window;
+ if (is_decl)
+ {
+ semsg(_("E1079: Cannot declare a window variable: %s"), name);
+ goto theend;
+ }
+ }
+ else if (STRNCMP(arg, "t:", 2) == 0)
+ {
+ dest = dest_tab;
+ if (is_decl)
+ {
+ semsg(_("E1080: Cannot declare a tab variable: %s"), name);
+ goto theend;
+ }
+ }
else if (STRNCMP(arg, "v:", 2) == 0)
{
typval_T *vtv;
***************
*** 4245,4250 ****
--- 4278,4292 ----
case dest_global:
generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
break;
+ case dest_buffer:
+ generate_LOAD(cctx, ISN_LOADB, 0, name + 2, type);
+ break;
+ case dest_window:
+ generate_LOAD(cctx, ISN_LOADW, 0, name + 2, type);
+ break;
+ case dest_tab:
+ generate_LOAD(cctx, ISN_LOADT, 0, name + 2, type);
+ break;
case dest_script:
compile_load_scriptvar(cctx,
name + (name[1] == ':' ? 2 : 0), NULL, NULL, TRUE);
***************
*** 4410,4415 ****
--- 4452,4469 ----
// include g: with the name, easier to execute that way
generate_STORE(cctx, ISN_STOREG, 0, name);
break;
+ case dest_buffer:
+ // include b: with the name, easier to execute that way
+ generate_STORE(cctx, ISN_STOREB, 0, name);
+ break;
+ case dest_window:
+ // include w: with the name, easier to execute that way
+ generate_STORE(cctx, ISN_STOREW, 0, name);
+ break;
+ case dest_tab:
+ // include t: with the name, easier to execute that way
+ generate_STORE(cctx, ISN_STORET, 0, name);
+ break;
case dest_env:
generate_STORE(cctx, ISN_STOREENV, 0, name + 1);
break;
***************
*** 6189,6200 ****
--- 6243,6260 ----
case ISN_EXEC:
case ISN_LOADENV:
case ISN_LOADG:
+ case ISN_LOADB:
+ case ISN_LOADW:
+ case ISN_LOADT:
case ISN_LOADOPT:
case ISN_MEMBER:
case ISN_PUSHEXC:
case ISN_PUSHS:
case ISN_STOREENV:
case ISN_STOREG:
+ case ISN_STOREB:
+ case ISN_STOREW:
+ case ISN_STORET:
case ISN_PUSHFUNC:
vim_free(isn->isn_arg.string);
break;
*** ../vim-8.2.0599/src/vim9execute.c 2020-04-18 19:53:24.531912284 +0200
--- src/vim9execute.c 2020-04-19 14:19:23.685767255 +0200
***************
*** 446,451 ****
--- 446,452 ----
restore_funccal();
}
+
/*
* Execute a function by "name".
* This can be a builtin function, user function or a funcref.
***************
*** 757,772 ****
}
break;
! // load g: variable
case ISN_LOADG:
! {
! dictitem_T *di = find_var_in_ht(get_globvar_ht(), 0,
! iptr->isn_arg.string, TRUE);
if (di == NULL)
{
! semsg(_("E121: Undefined variable: g:%s"),
! iptr->isn_arg.string);
goto failed;
}
else
--- 758,799 ----
}
break;
! // load g:/b:/w:/t: variable
case ISN_LOADG:
! case ISN_LOADB:
! case ISN_LOADW:
! case ISN_LOADT:
! {
! dictitem_T *di = NULL;
! hashtab_T *ht = NULL;
! char namespace;
! switch (iptr->isn_type)
! {
! case ISN_LOADG:
! ht = get_globvar_ht();
! namespace = 'g';
! break;
! case ISN_LOADB:
! ht = &curbuf->b_vars->dv_hashtab;
! namespace = 'b';
! break;
! case ISN_LOADW:
! ht = &curwin->w_vars->dv_hashtab;
! namespace = 'w';
! break;
! case ISN_LOADT:
! ht = &curtab->tp_vars->dv_hashtab;
! namespace = 't';
! break;
! default: // Cannot reach here
! goto failed;
! }
! di = find_var_in_ht(ht, 0, iptr->isn_arg.string, TRUE);
if (di == NULL)
{
! semsg(_("E121: Undefined variable: %c:%s"),
! namespace, iptr->isn_arg.string);
goto failed;
}
else
***************
*** 925,937 ****
goto failed;
break;
! // store g: variable
case ISN_STOREG:
{
dictitem_T *di;
--ectx.ec_stack.ga_len;
! di = find_var_in_ht(get_globvar_ht(), 0,
iptr->isn_arg.string + 2, TRUE);
if (di == NULL)
store_var(iptr->isn_arg.string, STACK_TV_BOT(0));
--- 952,985 ----
goto failed;
break;
! // store g:/b:/w:/t: variable
case ISN_STOREG:
+ case ISN_STOREB:
+ case ISN_STOREW:
+ case ISN_STORET:
{
dictitem_T *di;
+ hashtab_T *ht;
+ switch (iptr->isn_type)
+ {
+ case ISN_STOREG:
+ ht = get_globvar_ht();
+ break;
+ case ISN_STOREB:
+ ht = &curbuf->b_vars->dv_hashtab;
+ break;
+ case ISN_STOREW:
+ ht = &curwin->w_vars->dv_hashtab;
+ break;
+ case ISN_STORET:
+ ht = &curtab->tp_vars->dv_hashtab;
+ break;
+ default: // Cannot reach here
+ goto failed;
+ }
--ectx.ec_stack.ga_len;
! di = find_var_in_ht(ht, 0,
iptr->isn_arg.string + 2, TRUE);
if (di == NULL)
store_var(iptr->isn_arg.string, STACK_TV_BOT(0));
***************
*** 1918,1923 ****
--- 1966,1980 ----
case ISN_LOADG:
smsg("%4d LOADG g:%s", current, iptr->isn_arg.string);
break;
+ case ISN_LOADB:
+ smsg("%4d LOADB b:%s", current, iptr->isn_arg.string);
+ break;
+ case ISN_LOADW:
+ smsg("%4d LOADW w:%s", current, iptr->isn_arg.string);
+ break;
+ case ISN_LOADT:
+ smsg("%4d LOADT t:%s", current, iptr->isn_arg.string);
+ break;
case ISN_LOADOPT:
smsg("%4d LOADOPT %s", current, iptr->isn_arg.string);
break;
***************
*** 1943,1948 ****
--- 2000,2014 ----
case ISN_STOREG:
smsg("%4d STOREG %s", current, iptr->isn_arg.string);
break;
+ case ISN_STOREB:
+ smsg("%4d STOREB %s", current, iptr->isn_arg.string);
+ break;
+ case ISN_STOREW:
+ smsg("%4d STOREW %s", current, iptr->isn_arg.string);
+ break;
+ case ISN_STORET:
+ smsg("%4d STORET %s", current, iptr->isn_arg.string);
+ break;
case ISN_STORES:
{
scriptitem_T *si = SCRIPT_ITEM(
*** ../vim-8.2.0599/src/version.c 2020-04-19 14:02:22.427687032 +0200
--- src/version.c 2020-04-19 14:21:27.801488599 +0200
***************
*** 748,749 ****
--- 748,751 ----
{ /* Add new patch number below this line */
+ /**/
+ 600,
/**/
--
The only way the average employee can speak to an executive is by taking a
second job as a golf caddie.
(Scott Adams - The Dilbert principle)
/// 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/202004191241.03JCfNUL003247%40masaka.moolenaar.net.