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<string> = #{key: 'value'}
    let dict2: dict<number> = #{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('<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')
***************
*** 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('<SNR>\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('<SNR>\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('<SNR>\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 -- [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/202002022124.012LOo1j031539%40masaka.moolenaar.net.

Raspunde prin e-mail lui