Patch 8.2.0201
Problem: Cannot assign to an imported variable.
Solution: Make it work.
Files: src/evalvars.c, src/vim9compile.c, src/proto/vim9compile.pro,
src/userfunc.c, src/testdir/test_vim9_script.vim
*** ../vim-8.2.0200/src/evalvars.c 2020-02-02 22:24:00.624827188 +0100
--- src/evalvars.c 2020-02-02 23:01:32.498917653 +0100
***************
*** 2296,2302 ****
if (tv == NULL && current_sctx.sc_version == SCRIPT_VERSION_VIM9)
{
! imported_T *import = find_imported(name, NULL);
// imported variable from another script
if (import != NULL)
--- 2296,2302 ----
if (tv == NULL && current_sctx.sc_version == SCRIPT_VERSION_VIM9)
{
! imported_T *import = find_imported(name, 0, NULL);
// imported variable from another script
if (import != NULL)
***************
*** 2472,2478 ****
res = HASHITEM_EMPTY(hi) ? -1 : 1;
// if not script-local, then perhaps imported
! if (res == -1 && find_imported(p, NULL) != NULL)
res = 1;
if (p != buffer)
--- 2472,2478 ----
res = HASHITEM_EMPTY(hi) ? -1 : 1;
// if not script-local, then perhaps imported
! if (res == -1 && find_imported(p, 0, NULL) != NULL)
res = 1;
if (p != buffer)
*** ../vim-8.2.0200/src/vim9compile.c 2020-02-02 22:24:00.624827188 +0100
--- src/vim9compile.c 2020-02-03 20:50:05.549112994 +0100
***************
*** 1467,1473 ****
* Find "name" in imported items of the current script/
*/
imported_T *
! find_imported(char_u *name, cctx_T *cctx)
{
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
int idx;
--- 1467,1473 ----
* Find "name" in imported items of the current script/
*/
imported_T *
! find_imported(char_u *name, size_t len, cctx_T *cctx)
{
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
int idx;
***************
*** 1478,1484 ****
imported_T *import = ((imported_T *)cctx->ctx_imports.ga_data)
+ idx;
! if (STRCMP(name, import->imp_name) == 0)
return import;
}
--- 1478,1486 ----
imported_T *import = ((imported_T *)cctx->ctx_imports.ga_data)
+ idx;
! if (len == 0 ? STRCMP(name, import->imp_name) == 0
! : STRLEN(import->imp_name) == len
! && STRNCMP(name, import->imp_name, len) == 0)
return import;
}
***************
*** 1486,1492 ****
{
imported_T *import = ((imported_T *)si->sn_imports.ga_data) + idx;
! if (STRCMP(name, import->imp_name) == 0)
return import;
}
return NULL;
--- 1488,1496 ----
{
imported_T *import = ((imported_T *)si->sn_imports.ga_data) + idx;
! if (len == 0 ? STRCMP(name, import->imp_name) == 0
! : STRLEN(import->imp_name) == len
! && STRNCMP(name, import->imp_name, len) == 0)
return import;
}
return NULL;
***************
*** 1517,1523 ****
return OK;
}
! import = find_imported(name, cctx);
if (import != NULL)
{
// TODO: check this is a variable, not a function
--- 1521,1527 ----
return OK;
}
! import = find_imported(name, 0, cctx);
if (import != NULL)
{
// TODO: check this is a variable, not a function
***************
*** 3071,3076 ****
--- 3075,3090 ----
[cctx->ctx_lnum]);
}
+ typedef enum {
+ dest_local,
+ dest_option,
+ dest_env,
+ dest_global,
+ dest_vimvar,
+ dest_script,
+ dest_reg,
+ } assign_dest_T;
+
/*
* compile "let var [= expr]", "const var = expr" and "var = expr"
* "arg" points to "var".
***************
*** 3086,3099 ****
garray_T *instr = &cctx->ctx_instr;
int idx = -1;
char_u *op;
- int option = FALSE;
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;
type_T *type;
--- 3100,3109 ----
garray_T *instr = &cctx->ctx_instr;
int idx = -1;
char_u *op;
int opt_type;
+ assign_dest_T dest = dest_local;
int opt_flags = 0;
int vimvaridx = -1;
int oplen = 0;
int heredoc = FALSE;
type_T *type;
***************
*** 3125,3131 ****
long numval;
char_u *stringval = NULL;
! option = TRUE;
if (cmdidx == CMD_const)
{
emsg(_(e_const_option));
--- 3135,3141 ----
long numval;
char_u *stringval = NULL;
! dest = dest_option;
if (cmdidx == CMD_const)
{
emsg(_(e_const_option));
***************
*** 3159,3165 ****
}
else if (*arg == '$')
{
! env = TRUE;
if (is_decl)
{
semsg(_("E1065: Cannot declare an environment variable: %s"), name);
--- 3169,3175 ----
}
else if (*arg == '$')
{
! dest = dest_env;
if (is_decl)
{
semsg(_("E1065: Cannot declare an environment variable: %s"), name);
***************
*** 3173,3179 ****
emsg_invreg(arg[1]);
return FAIL;
}
! reg = TRUE;
if (is_decl)
{
semsg(_("E1066: Cannot declare a register: %s"), name);
--- 3183,3189 ----
emsg_invreg(arg[1]);
return FAIL;
}
! dest = dest_reg;
if (is_decl)
{
semsg(_("E1066: Cannot declare a register: %s"), name);
***************
*** 3182,3188 ****
}
else if (STRNCMP(arg, "g:", 2) == 0)
{
! global = TRUE;
if (is_decl)
{
semsg(_("E1016: Cannot declare a global variable: %s"), name);
--- 3192,3198 ----
}
else if (STRNCMP(arg, "g:", 2) == 0)
{
! dest = dest_global;
if (is_decl)
{
semsg(_("E1016: Cannot declare a global variable: %s"), name);
***************
*** 3197,3202 ****
--- 3207,3213 ----
semsg(_(e_var_notfound), arg);
goto theend;
}
+ dest = dest_vimvar;
if (is_decl)
{
semsg(_("E1064: Cannot declare a v: variable: %s"), name);
***************
*** 3232,3240 ****
}
else if ((STRNCMP(arg, "s:", 2) == 0
? lookup_script(arg + 2, varlen - 2)
! : lookup_script(arg, varlen)) == OK)
{
! script = TRUE;
if (is_decl)
{
semsg(_("E1054: Variable already declared in the script: %s"),
--- 3243,3252 ----
}
else if ((STRNCMP(arg, "s:", 2) == 0
? lookup_script(arg + 2, varlen - 2)
! : lookup_script(arg, varlen)) == OK
! || find_imported(arg, varlen, cctx) != NULL)
{
! dest = dest_script;
if (is_decl)
{
semsg(_("E1054: Variable already declared in the script: %s"),
***************
*** 3244,3250 ****
}
}
! if (!option)
{
if (is_decl && *p == ':')
{
--- 3256,3262 ----
}
}
! if (dest != dest_option)
{
if (is_decl && *p == ':')
{
***************
*** 3279,3293 ****
semsg(_(e_white_both), buf);
}
! if (oplen == 3 && !heredoc && !global && type->tt_type != VAR_STRING
! && type->tt_type != VAR_UNKNOWN)
{
emsg("E1019: Can only concatenate to string");
goto theend;
}
// +=, /=, etc. require an existing variable
! if (idx < 0 && !global && !env && !reg && !option)
{
if (oplen > 1 && !heredoc)
{
--- 3291,3305 ----
semsg(_(e_white_both), buf);
}
! if (oplen == 3 && !heredoc && dest != dest_global
! && type->tt_type != VAR_STRING && type->tt_type != VAR_UNKNOWN)
{
emsg("E1019: Can only concatenate to string");
goto theend;
}
// +=, /=, etc. require an existing variable
! if (idx < 0 && dest == dest_local)
{
if (oplen > 1 && !heredoc)
{
***************
*** 3328,3347 ****
// for "+=", "*=", "..=" etc. first load the current value
if (*op != '=')
{
! if (option)
! // TODO: check the option exists
! 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);
}
// compile the expression
--- 3340,3371 ----
// for "+=", "*=", "..=" etc. first load the current value
if (*op != '=')
{
! switch (dest)
! {
! case dest_option:
! // TODO: check the option exists
! generate_LOAD(cctx, ISN_LOADOPT, 0, name + 1, type);
! break;
! case dest_global:
! generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
! break;
! case dest_script:
! compile_load_scriptvar(cctx, name);
! break;
! case dest_env:
! // Include $ in the name here
! generate_LOAD(cctx, ISN_LOADENV, 0, name, type);
! break;
! case dest_reg:
! generate_LOAD(cctx, ISN_LOADREG, arg[1], NULL, &t_string);
! break;
! case dest_vimvar:
! generate_LOADV(cctx, name + 2, TRUE);
! break;
! case dest_local:
! generate_LOAD(cctx, ISN_LOAD, idx, NULL, type);
! break;
! }
}
// compile the expression
***************
*** 3377,3383 ****
emsg(_("E1021: const requires a value"));
goto theend;
}
! else if (!has_type || option)
{
emsg(_("E1022: type or initialization required"));
goto theend;
--- 3401,3407 ----
emsg(_("E1021: const requires a value"));
goto theend;
}
! else if (!has_type || dest == dest_option)
{
emsg(_("E1022: type or initialization required"));
goto theend;
***************
*** 3427,3475 ****
}
}
! 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
! {
! isn_T *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
! // optimization: turn "var = 123" from ISN_PUSHNR + ISN_STORE into
! // ISN_STORENR
! if (instr->ga_len == instr_count + 1 && isn->isn_type == ISN_PUSHNR)
! {
! varnumber_T val = isn->isn_arg.number;
! garray_T *stack = &cctx->ctx_type_stack;
! isn->isn_type = ISN_STORENR;
! isn->isn_arg.storenr.str_idx = idx;
! isn->isn_arg.storenr.str_val = val;
! if (stack->ga_len > 0)
! --stack->ga_len;
! }
! else
! generate_STORE(cctx, ISN_STORE, idx, NULL);
}
ret = p;
--- 3451,3518 ----
}
}
! switch (dest)
{
! case dest_option:
! generate_STOREOPT(cctx, name + 1, opt_flags);
! break;
! case dest_global:
! // include g: with the name, easier to execute that way
! generate_STORE(cctx, ISN_STOREG, 0, name);
! break;
! case dest_env:
! generate_STORE(cctx, ISN_STOREENV, 0, name + 1);
! break;
! case dest_reg:
! generate_STORE(cctx, ISN_STOREREG, name[1], NULL);
! break;
! case dest_vimvar:
! generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL);
! break;
! case dest_script:
! {
! char_u *rawname = name + (name[1] == ':' ? 2 : 0);
! imported_T *import = NULL;
! int sid = current_sctx.sc_sid;
! if (name[1] != ':')
! {
! import = find_imported(name, 0, cctx);
! if (import != NULL)
! sid = import->imp_sid;
! }
! idx = get_script_item_idx(sid, rawname, TRUE);
! // TODO: specific type
! if (idx < 0)
! generate_OLDSCRIPT(cctx, ISN_STORES, rawname, sid, &t_any);
! else
! generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT,
! sid, idx, &t_any);
! }
! break;
! case dest_local:
! {
! isn_T *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
! // optimization: turn "var = 123" from ISN_PUSHNR + ISN_STORE
! // into ISN_STORENR
! if (instr->ga_len == instr_count + 1
! && isn->isn_type == ISN_PUSHNR)
! {
! varnumber_T val = isn->isn_arg.number;
! garray_T *stack = &cctx->ctx_type_stack;
!
! isn->isn_type = ISN_STORENR;
! isn->isn_arg.storenr.str_idx = idx;
! isn->isn_arg.storenr.str_val = val;
! if (stack->ga_len > 0)
! --stack->ga_len;
! }
! else
! generate_STORE(cctx, ISN_STORE, idx, NULL);
! }
! break;
}
ret = p;
***************
*** 4619,4625 ****
// "funcname(" is always a function call.
// "varname[]" is an expression.
- // "g:varname" is an expression.
// "varname->expr" is an expression.
if (*p == '('
|| *p == '['
--- 4662,4667 ----
***************
*** 4643,4649 ****
|| *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)
{
line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx);
if (line == NULL)
--- 4685,4692 ----
|| *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
! || find_imported(ea.cmd, p - ea.cmd, &cctx) != NULL)
{
line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx);
if (line == NULL)
*** ../vim-8.2.0200/src/proto/vim9compile.pro 2020-01-26 15:52:33.023833239
+0100
--- src/proto/vim9compile.pro 2020-02-02 23:01:55.478792829 +0100
***************
*** 4,10 ****
char *vartype_name(vartype_T type);
char *type_name(type_T *type, char **tofree);
int get_script_item_idx(int sid, char_u *name, int check_writable);
! imported_T *find_imported(char_u *name, cctx_T *cctx);
char_u *to_name_end(char_u *arg);
char_u *to_name_const_end(char_u *arg);
int assignment_len(char_u *p, int *heredoc);
--- 4,10 ----
char *vartype_name(vartype_T type);
char *type_name(type_T *type, char **tofree);
int get_script_item_idx(int sid, char_u *name, int check_writable);
! imported_T *find_imported(char_u *name, size_t len, cctx_T *cctx);
char_u *to_name_end(char_u *arg);
char_u *to_name_const_end(char_u *arg);
int assignment_len(char_u *p, int *heredoc);
*** ../vim-8.2.0200/src/userfunc.c 2020-02-02 17:22:23.438043236 +0100
--- src/userfunc.c 2020-02-02 23:01:48.194832260 +0100
***************
*** 678,684 ****
return func;
// Find imported funcion before global one.
! imported = find_imported(name, cctx);
if (imported != NULL && imported->imp_funcname != NULL)
{
hi = hash_find(&func_hashtab, imported->imp_funcname);
--- 678,684 ----
return func;
// Find imported funcion before global one.
! imported = find_imported(name, 0, cctx);
if (imported != NULL && imported->imp_funcname != NULL)
{
hi = hash_find(&func_hashtab, imported->imp_funcname);
*** ../vim-8.2.0200/src/testdir/test_vim9_script.vim 2020-02-02
22:24:00.624827188 +0100
--- src/testdir/test_vim9_script.vim 2020-02-03 20:35:45.627973293 +0100
***************
*** 320,328 ****
\ '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')
--- 320,330 ----
\ 'import exported from "' .. escape(getcwd(), '\') ..
'/Xexport_abs.vim"',
\ 'def UseExported()',
\ ' g:imported_abs = exported',
+ \ ' exported = 8888',
+ \ ' g:imported_after = exported',
\ 'enddef',
\ 'UseExported()',
! \ 'g:import_disassembled = execute("disass UseExported")',
\ ]
writefile(import_lines, 'Ximport_abs.vim')
writefile(s:export_script_lines, 'Xexport_abs.vim')
***************
*** 330,341 ****
source Ximport_abs.vim
assert_equal(9876, g:imported_abs)
assert_match('<SNR>\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')
--- 332,350 ----
source Ximport_abs.vim
assert_equal(9876, g:imported_abs)
+ assert_equal(8888, g:imported_after)
assert_match('<SNR>\d\+_UseExported.*'
\ .. 'g:imported_abs = exported.*'
\ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
! \ .. '1 STOREG g:imported_abs.*'
! \ .. 'exported = 8888.*'
! \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
! \ .. 'g:imported_after = exported.*'
! \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
! \ .. '5 STOREG g:imported_after.*'
! \, g:import_disassembled)
unlet g:imported_abs
! unlet g:import_disassembled
delete('Ximport_abs.vim')
delete('Xexport_abs.vim')
*** ../vim-8.2.0200/src/version.c 2020-02-02 22:24:00.628827172 +0100
--- src/version.c 2020-02-03 20:50:32.225015557 +0100
***************
*** 744,745 ****
--- 744,747 ----
{ /* Add new patch number below this line */
+ /**/
+ 201,
/**/
--
If Pacman had affected us as kids we'd be running around in dark rooms,
munching pills and listening to repetitive music.
-- Marcus Brigstocke
/// 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/202002031951.013JpWRc017174%40masaka.moolenaar.net.