comparison src/evalvars.c @ 19181:94eda51ba9ba v8.2.0149

patch 8.2.0149: maintaining a Vim9 branch separately is more work Commit: https://github.com/vim/vim/commit/8a7d6542b33e5d2b352262305c3bfdb2d14e1cf8 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jan 26 15:56:19 2020 +0100 patch 8.2.0149: maintaining a Vim9 branch separately is more work Problem: Maintaining a Vim9 branch separately is more work. Solution: Merge the Vim9 script changes.
author Bram Moolenaar <Bram@vim.org>
date Sun, 26 Jan 2020 16:00:05 +0100
parents 44c6498535c9
children 133ef7ba4e4e
comparison
equal deleted inserted replaced
19180:8edf0aeb71b9 19181:94eda51ba9ba
13 13
14 #include "vim.h" 14 #include "vim.h"
15 15
16 #if defined(FEAT_EVAL) || defined(PROTO) 16 #if defined(FEAT_EVAL) || defined(PROTO)
17 17
18 static char *e_letunexp = N_("E18: Unexpected characters in :let");
19
20 static dictitem_T globvars_var; // variable used for g: 18 static dictitem_T globvars_var; // variable used for g:
21 static dict_T globvardict; // Dictionary with g: variables 19 static dict_T globvardict; // Dictionary with g: variables
22 #define globvarht globvardict.dv_hashtab 20 #define globvarht globvardict.dv_hashtab
23 21
24 /* 22 /*
38 #define VV_COMPAT 1 // compatible, also used without "v:" 36 #define VV_COMPAT 1 // compatible, also used without "v:"
39 #define VV_RO 2 // read-only 37 #define VV_RO 2 // read-only
40 #define VV_RO_SBX 4 // read-only in the sandbox 38 #define VV_RO_SBX 4 // read-only in the sandbox
41 39
42 #define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}} 40 #define VV_NAME(s, t) s, {{t, 0, {0}}, 0, {0}}
41
42 typedef struct vimvar vimvar_T;
43 43
44 static struct vimvar 44 static struct vimvar
45 { 45 {
46 char *vv_name; // name of variable, without v: 46 char *vv_name; // name of variable, without v:
47 dictitem16_T vv_di; // value and name for key (max 16 chars!) 47 dictitem16_T vv_di; // value and name for key (max 16 chars!)
161 #define vimvarht vimvardict.dv_hashtab 161 #define vimvarht vimvardict.dv_hashtab
162 162
163 // for VIM_VERSION_ defines 163 // for VIM_VERSION_ defines
164 #include "version.h" 164 #include "version.h"
165 165
166 #define SCRIPT_SV(id) (SCRIPT_ITEM(id).sn_vars)
167 #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
168
169 static void ex_let_const(exarg_T *eap, int is_const); 166 static void ex_let_const(exarg_T *eap, int is_const);
170 static char_u *skip_var_one(char_u *arg); 167 static char_u *skip_var_one(char_u *arg, int include_type);
171 static void list_glob_vars(int *first); 168 static void list_glob_vars(int *first);
172 static void list_buf_vars(int *first); 169 static void list_buf_vars(int *first);
173 static void list_win_vars(int *first); 170 static void list_win_vars(int *first);
174 static void list_tab_vars(int *first); 171 static void list_tab_vars(int *first);
175 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first); 172 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first);
176 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int is_const, char_u *endchars, char_u *op); 173 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int flags, char_u *endchars, char_u *op);
177 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep); 174 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep);
178 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit); 175 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit);
179 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock); 176 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock);
180 static void item_lock(typval_T *tv, int deep, int lock); 177 static void item_lock(typval_T *tv, int deep, int lock);
181 static void delete_var(hashtab_T *ht, hashitem_T *hi); 178 static void delete_var(hashtab_T *ht, hashitem_T *hi);
542 * The {marker} is a string. If the optional 'trim' word is supplied before the 539 * The {marker} is a string. If the optional 'trim' word is supplied before the
543 * marker, then the leading indentation before the lines (matching the 540 * marker, then the leading indentation before the lines (matching the
544 * indentation in the 'cmd' line) is stripped. 541 * indentation in the 'cmd' line) is stripped.
545 * Returns a List with {lines} or NULL. 542 * Returns a List with {lines} or NULL.
546 */ 543 */
547 static list_T * 544 list_T *
548 heredoc_get(exarg_T *eap, char_u *cmd) 545 heredoc_get(exarg_T *eap, char_u *cmd)
549 { 546 {
550 char_u *theline; 547 char_u *theline;
551 char_u *marker; 548 char_u *marker;
552 list_T *l; 549 list_T *l;
667 * ":let var /= expr" assignment command. 664 * ":let var /= expr" assignment command.
668 * ":let var %= expr" assignment command. 665 * ":let var %= expr" assignment command.
669 * ":let var .= expr" assignment command. 666 * ":let var .= expr" assignment command.
670 * ":let var ..= expr" assignment command. 667 * ":let var ..= expr" assignment command.
671 * ":let [var1, var2] = expr" unpack list. 668 * ":let [var1, var2] = expr" unpack list.
669 * ":let var =<< ..." heredoc
672 */ 670 */
673 void 671 void
674 ex_let(exarg_T *eap) 672 ex_let(exarg_T *eap)
675 { 673 {
676 ex_let_const(eap, FALSE); 674 ex_let_const(eap, FALSE);
699 int semicolon = 0; 697 int semicolon = 0;
700 char_u op[2]; 698 char_u op[2];
701 char_u *argend; 699 char_u *argend;
702 int first = TRUE; 700 int first = TRUE;
703 int concat; 701 int concat;
704 702 int flags = is_const ? LET_IS_CONST : 0;
705 argend = skip_var_list(arg, &var_count, &semicolon); 703
704 // detect Vim9 assignment without ":let" or ":const"
705 if (eap->arg == eap->cmd)
706 flags |= LET_NO_COMMAND;
707
708 argend = skip_var_list(arg, TRUE, &var_count, &semicolon);
706 if (argend == NULL) 709 if (argend == NULL)
707 return; 710 return;
708 if (argend > arg && argend[-1] == '.') // for var.='str' 711 if (argend > arg && argend[-1] == '.') // for var.='str'
709 --argend; 712 --argend;
710 expr = skipwhite(argend); 713 expr = skipwhite(argend);
747 if (!eap->skip) 750 if (!eap->skip)
748 { 751 {
749 op[0] = '='; 752 op[0] = '=';
750 op[1] = NUL; 753 op[1] = NUL;
751 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 754 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count,
752 is_const, op); 755 flags, op);
753 } 756 }
754 clear_tv(&rettv); 757 clear_tv(&rettv);
755 } 758 }
756 } 759 }
757 else 760 else
781 --emsg_skip; 784 --emsg_skip;
782 } 785 }
783 else if (i != FAIL) 786 else if (i != FAIL)
784 { 787 {
785 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 788 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count,
786 is_const, op); 789 flags, op);
787 clear_tv(&rettv); 790 clear_tv(&rettv);
788 } 791 }
789 } 792 }
790 } 793 }
791 794
802 char_u *arg_start, 805 char_u *arg_start,
803 typval_T *tv, 806 typval_T *tv,
804 int copy, // copy values from "tv", don't move 807 int copy, // copy values from "tv", don't move
805 int semicolon, // from skip_var_list() 808 int semicolon, // from skip_var_list()
806 int var_count, // from skip_var_list() 809 int var_count, // from skip_var_list()
807 int is_const, // lock variables for const 810 int flags, // LET_IS_CONST and/or LET_NO_COMMAND
808 char_u *op) 811 char_u *op)
809 { 812 {
810 char_u *arg = arg_start; 813 char_u *arg = arg_start;
811 list_T *l; 814 list_T *l;
812 int i; 815 int i;
814 typval_T ltv; 817 typval_T ltv;
815 818
816 if (*arg != '[') 819 if (*arg != '[')
817 { 820 {
818 // ":let var = expr" or ":for var in list" 821 // ":let var = expr" or ":for var in list"
819 if (ex_let_one(arg, tv, copy, is_const, op, op) == NULL) 822 if (ex_let_one(arg, tv, copy, flags, op, op) == NULL)
820 return FAIL; 823 return FAIL;
821 return OK; 824 return OK;
822 } 825 }
823 826
824 // ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 827 // ":let [v1, v2] = list" or ":for [v1, v2] in listlist"
842 845
843 item = l->lv_first; 846 item = l->lv_first;
844 while (*arg != ']') 847 while (*arg != ']')
845 { 848 {
846 arg = skipwhite(arg + 1); 849 arg = skipwhite(arg + 1);
847 arg = ex_let_one(arg, &item->li_tv, TRUE, is_const, 850 arg = ex_let_one(arg, &item->li_tv, TRUE, flags, (char_u *)",;]", op);
848 (char_u *)",;]", op);
849 item = item->li_next; 851 item = item->li_next;
850 if (arg == NULL) 852 if (arg == NULL)
851 return FAIL; 853 return FAIL;
852 854
853 arg = skipwhite(arg); 855 arg = skipwhite(arg);
867 ltv.v_type = VAR_LIST; 869 ltv.v_type = VAR_LIST;
868 ltv.v_lock = 0; 870 ltv.v_lock = 0;
869 ltv.vval.v_list = l; 871 ltv.vval.v_list = l;
870 l->lv_refcount = 1; 872 l->lv_refcount = 1;
871 873
872 arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE, is_const, 874 arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE, flags,
873 (char_u *)"]", op); 875 (char_u *)"]", op);
874 clear_tv(&ltv); 876 clear_tv(&ltv);
875 if (arg == NULL) 877 if (arg == NULL)
876 return FAIL; 878 return FAIL;
877 break; 879 break;
894 * Return NULL for an error. 896 * Return NULL for an error.
895 */ 897 */
896 char_u * 898 char_u *
897 skip_var_list( 899 skip_var_list(
898 char_u *arg, 900 char_u *arg,
901 int include_type,
899 int *var_count, 902 int *var_count,
900 int *semicolon) 903 int *semicolon)
901 { 904 {
902 char_u *p, *s; 905 char_u *p, *s;
903 906
906 // "[var, var]": find the matching ']'. 909 // "[var, var]": find the matching ']'.
907 p = arg; 910 p = arg;
908 for (;;) 911 for (;;)
909 { 912 {
910 p = skipwhite(p + 1); // skip whites after '[', ';' or ',' 913 p = skipwhite(p + 1); // skip whites after '[', ';' or ','
911 s = skip_var_one(p); 914 s = skip_var_one(p, TRUE);
912 if (s == p) 915 if (s == p)
913 { 916 {
914 semsg(_(e_invarg2), p); 917 semsg(_(e_invarg2), p);
915 return NULL; 918 return NULL;
916 } 919 }
935 } 938 }
936 } 939 }
937 return p + 1; 940 return p + 1;
938 } 941 }
939 else 942 else
940 return skip_var_one(arg); 943 return skip_var_one(arg, include_type);
941 } 944 }
942 945
943 /* 946 /*
944 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, 947 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key,
945 * l[idx]. 948 * l[idx].
949 * In Vim9 script also skip over ": type" if "include_type" is TRUE.
946 */ 950 */
947 static char_u * 951 static char_u *
948 skip_var_one(char_u *arg) 952 skip_var_one(char_u *arg, int include_type)
949 { 953 {
954 char_u *end;
955
950 if (*arg == '@' && arg[1] != NUL) 956 if (*arg == '@' && arg[1] != NUL)
951 return arg + 2; 957 return arg + 2;
952 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 958 end = find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg,
953 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 959 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
960 if (include_type && current_sctx.sc_version == SCRIPT_VERSION_VIM9
961 && *end == ':')
962 {
963 end = skip_type(skipwhite(end + 1));
964 }
965 return end;
954 } 966 }
955 967
956 /* 968 /*
957 * List variables for hashtab "ht" with prefix "prefix". 969 * List variables for hashtab "ht" with prefix "prefix".
958 * If "empty" is TRUE also list NULL strings as empty strings. 970 * If "empty" is TRUE also list NULL strings as empty strings.
1139 static char_u * 1151 static char_u *
1140 ex_let_one( 1152 ex_let_one(
1141 char_u *arg, // points to variable name 1153 char_u *arg, // points to variable name
1142 typval_T *tv, // value to assign to variable 1154 typval_T *tv, // value to assign to variable
1143 int copy, // copy value from "tv" 1155 int copy, // copy value from "tv"
1144 int is_const, // lock variable for const 1156 int flags, // LET_IS_CONST and/or LET_NO_COMMAND
1145 char_u *endchars, // valid chars after variable name or NULL 1157 char_u *endchars, // valid chars after variable name or NULL
1146 char_u *op) // "+", "-", "." or NULL 1158 char_u *op) // "+", "-", "." or NULL
1147 { 1159 {
1148 int c1; 1160 int c1;
1149 char_u *name; 1161 char_u *name;
1154 char_u *tofree = NULL; 1166 char_u *tofree = NULL;
1155 1167
1156 // ":let $VAR = expr": Set environment variable. 1168 // ":let $VAR = expr": Set environment variable.
1157 if (*arg == '$') 1169 if (*arg == '$')
1158 { 1170 {
1159 if (is_const) 1171 if (flags & LET_IS_CONST)
1160 { 1172 {
1161 emsg(_("E996: Cannot lock an environment variable")); 1173 emsg(_("E996: Cannot lock an environment variable"));
1162 return NULL; 1174 return NULL;
1163 } 1175 }
1164 // Find the end of the name. 1176 // Find the end of the name.
1212 // ":let &option = expr": Set option value. 1224 // ":let &option = expr": Set option value.
1213 // ":let &l:option = expr": Set local option value. 1225 // ":let &l:option = expr": Set local option value.
1214 // ":let &g:option = expr": Set global option value. 1226 // ":let &g:option = expr": Set global option value.
1215 else if (*arg == '&') 1227 else if (*arg == '&')
1216 { 1228 {
1217 if (is_const) 1229 if (flags & LET_IS_CONST)
1218 { 1230 {
1219 emsg(_("E996: Cannot lock an option")); 1231 emsg(_(e_const_option));
1220 return NULL; 1232 return NULL;
1221 } 1233 }
1222 // Find the end of the name. 1234 // Find the end of the name.
1223 p = find_option_end(&arg, &opt_flags); 1235 p = find_option_end(&arg, &opt_flags);
1224 if (p == NULL || (endchars != NULL 1236 if (p == NULL || (endchars != NULL
1279 } 1291 }
1280 1292
1281 // ":let @r = expr": Set register contents. 1293 // ":let @r = expr": Set register contents.
1282 else if (*arg == '@') 1294 else if (*arg == '@')
1283 { 1295 {
1284 if (is_const) 1296 if (flags & LET_IS_CONST)
1285 { 1297 {
1286 emsg(_("E996: Cannot lock a register")); 1298 emsg(_("E996: Cannot lock a register"));
1287 return NULL; 1299 return NULL;
1288 } 1300 }
1289 ++arg; 1301 ++arg;
1315 vim_free(ptofree); 1327 vim_free(ptofree);
1316 } 1328 }
1317 } 1329 }
1318 1330
1319 // ":let var = expr": Set internal variable. 1331 // ":let var = expr": Set internal variable.
1332 // ":let var: type = expr": Set internal variable with type.
1320 // ":let {expr} = expr": Idem, name made with curly braces 1333 // ":let {expr} = expr": Idem, name made with curly braces
1321 else if (eval_isnamec1(*arg) || *arg == '{') 1334 else if (eval_isnamec1(*arg) || *arg == '{')
1322 { 1335 {
1323 lval_T lv; 1336 lval_T lv;
1324 1337
1325 p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START); 1338 p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START);
1326 if (p != NULL && lv.ll_name != NULL) 1339 if (p != NULL && lv.ll_name != NULL)
1327 { 1340 {
1328 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 1341 if (endchars != NULL && vim_strchr(endchars,
1342 *skipwhite(lv.ll_name_end)) == NULL)
1329 emsg(_(e_letunexp)); 1343 emsg(_(e_letunexp));
1330 else 1344 else
1331 { 1345 {
1332 set_var_lval(&lv, p, tv, copy, is_const, op); 1346 set_var_lval(&lv, p, tv, copy, flags, op);
1333 arg_end = p; 1347 arg_end = p;
1334 } 1348 }
1335 } 1349 }
1336 clear_lval(&lv); 1350 clear_lval(&lv);
1337 } 1351 }
1655 tv->v_lock &= ~VAR_LOCKED; 1669 tv->v_lock &= ~VAR_LOCKED;
1656 1670
1657 switch (tv->v_type) 1671 switch (tv->v_type)
1658 { 1672 {
1659 case VAR_UNKNOWN: 1673 case VAR_UNKNOWN:
1674 case VAR_VOID:
1660 case VAR_NUMBER: 1675 case VAR_NUMBER:
1676 case VAR_BOOL:
1661 case VAR_STRING: 1677 case VAR_STRING:
1662 case VAR_FUNC: 1678 case VAR_FUNC:
1663 case VAR_PARTIAL: 1679 case VAR_PARTIAL:
1664 case VAR_FLOAT: 1680 case VAR_FLOAT:
1665 case VAR_BOOL:
1666 case VAR_SPECIAL: 1681 case VAR_SPECIAL:
1667 case VAR_JOB: 1682 case VAR_JOB:
1668 case VAR_CHANNEL: 1683 case VAR_CHANNEL:
1669 break; 1684 break;
1670 1685
1899 { 1914 {
1900 return &vimvardict; 1915 return &vimvardict;
1901 } 1916 }
1902 1917
1903 /* 1918 /*
1919 * Returns the index of a v:variable. Negative if not found.
1920 */
1921 int
1922 find_vim_var(char_u *name)
1923 {
1924 dictitem_T *di = find_var_in_ht(&vimvarht, 0, name, TRUE);
1925 struct vimvar *vv;
1926
1927 if (di == NULL)
1928 return -1;
1929 vv = (struct vimvar *)((char *)di - offsetof(vimvar_T, vv_di));
1930 return (int)(vv - vimvars);
1931 }
1932
1933
1934 /*
1904 * Set type of v: variable to "type". 1935 * Set type of v: variable to "type".
1905 */ 1936 */
1906 void 1937 void
1907 set_vim_var_type(int idx, vartype_T type) 1938 set_vim_var_type(int idx, vartype_T type)
1908 { 1939 {
1915 */ 1946 */
1916 void 1947 void
1917 set_vim_var_nr(int idx, varnumber_T val) 1948 set_vim_var_nr(int idx, varnumber_T val)
1918 { 1949 {
1919 vimvars[idx].vv_nr = val; 1950 vimvars[idx].vv_nr = val;
1951 }
1952
1953 char *
1954 get_vim_var_name(int idx)
1955 {
1956 return vimvars[idx].vv_name;
1920 } 1957 }
1921 1958
1922 /* 1959 /*
1923 * Get typval_T v: variable value. 1960 * Get typval_T v: variable value.
1924 */ 1961 */
2243 tv = &v->di_tv; 2280 tv = &v->di_tv;
2244 if (dip != NULL) 2281 if (dip != NULL)
2245 *dip = v; 2282 *dip = v;
2246 } 2283 }
2247 2284
2285 if (tv == NULL && current_sctx.sc_version == SCRIPT_VERSION_VIM9)
2286 {
2287 imported_T *import = find_imported(name, NULL);
2288
2289 // imported variable from another script
2290 if (import != NULL)
2291 {
2292 scriptitem_T *si = &SCRIPT_ITEM(import->imp_sid);
2293 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
2294 + import->imp_var_vals_idx;
2295 tv = sv->sv_tv;
2296 }
2297 }
2298
2248 if (tv == NULL) 2299 if (tv == NULL)
2249 { 2300 {
2250 if (rettv != NULL && verbose) 2301 if (rettv != NULL && verbose)
2251 semsg(_(e_undefvar), name); 2302 semsg(_(e_undefvar), name);
2252 ret = FAIL; 2303 ret = FAIL;
2364 } 2415 }
2365 return HI2DI(hi); 2416 return HI2DI(hi);
2366 } 2417 }
2367 2418
2368 /* 2419 /*
2420 * Get the script-local hashtab. NULL if not in a script context.
2421 */
2422 hashtab_T *
2423 get_script_local_ht(void)
2424 {
2425 scid_T sid = current_sctx.sc_sid;
2426
2427 if (sid > 0 && sid <= script_items.ga_len)
2428 return &SCRIPT_VARS(sid);
2429 return NULL;
2430 }
2431
2432 /*
2433 * Look for "name[len]" in script-local variables.
2434 * Return -1 when not found.
2435 */
2436 int
2437 lookup_scriptvar(char_u *name, size_t len, cctx_T *dummy UNUSED)
2438 {
2439 hashtab_T *ht = get_script_local_ht();
2440 char_u buffer[30];
2441 char_u *p;
2442 int res;
2443 hashitem_T *hi;
2444
2445 if (ht == NULL)
2446 return -1;
2447 if (len < sizeof(buffer) - 1)
2448 {
2449 vim_strncpy(buffer, name, len);
2450 p = buffer;
2451 }
2452 else
2453 {
2454 p = vim_strnsave(name, (int)len);
2455 if (p == NULL)
2456 return -1;
2457 }
2458
2459 hi = hash_find(ht, p);
2460 res = HASHITEM_EMPTY(hi) ? -1 : 1;
2461
2462 // if not script-local, then perhaps imported
2463 if (res == -1 && find_imported(p, NULL) != NULL)
2464 res = 1;
2465
2466 if (p != buffer)
2467 vim_free(p);
2468 return res;
2469 }
2470
2471 /*
2369 * Find the hashtab used for a variable name. 2472 * Find the hashtab used for a variable name.
2370 * Return NULL if the name is not valid. 2473 * Return NULL if the name is not valid.
2371 * Set "varname" to the start of name without ':'. 2474 * Set "varname" to the start of name without ':'.
2372 */ 2475 */
2373 hashtab_T * 2476 hashtab_T *
2393 if (!HASHITEM_EMPTY(hi)) 2496 if (!HASHITEM_EMPTY(hi))
2394 return &compat_hashtab; 2497 return &compat_hashtab;
2395 } 2498 }
2396 2499
2397 ht = get_funccal_local_ht(); 2500 ht = get_funccal_local_ht();
2398 if (ht == NULL) 2501 if (ht != NULL)
2399 return &globvarht; // global variable 2502 return ht; // local variable
2400 return ht; // local variable 2503
2504 // in Vim9 script items at the script level are script-local
2505 if (current_sctx.sc_version == SCRIPT_VERSION_VIM9)
2506 {
2507 ht = get_script_local_ht();
2508 if (ht != NULL)
2509 return ht;
2510 }
2511
2512 return &globvarht; // global variable
2401 } 2513 }
2402 *varname = name + 2; 2514 *varname = name + 2;
2403 if (*name == 'g') // global variable 2515 if (*name == 'g') // global variable
2404 return &globvarht; 2516 return &globvarht;
2405 // There must be no ':' or '#' in the rest of the name, unless g: is used 2517 // There must be no ':' or '#' in the rest of the name, unless g: is used
2412 return &curwin->w_vars->dv_hashtab; 2524 return &curwin->w_vars->dv_hashtab;
2413 if (*name == 't') // tab page variable 2525 if (*name == 't') // tab page variable
2414 return &curtab->tp_vars->dv_hashtab; 2526 return &curtab->tp_vars->dv_hashtab;
2415 if (*name == 'v') // v: variable 2527 if (*name == 'v') // v: variable
2416 return &vimvarht; 2528 return &vimvarht;
2417 if (*name == 'a') // a: function argument 2529 if (current_sctx.sc_version != SCRIPT_VERSION_VIM9)
2418 return get_funccal_args_ht(); 2530 {
2419 if (*name == 'l') // l: local function variable 2531 if (*name == 'a') // a: function argument
2420 return get_funccal_local_ht(); 2532 return get_funccal_args_ht();
2421 if (*name == 's' // script variable 2533 if (*name == 'l') // l: local function variable
2422 && current_sctx.sc_sid > 0 2534 return get_funccal_local_ht();
2423 && current_sctx.sc_sid <= script_items.ga_len) 2535 }
2424 return &SCRIPT_VARS(current_sctx.sc_sid); 2536 if (*name == 's') // script variable
2537 {
2538 ht = get_script_local_ht();
2539 if (ht != NULL)
2540 return ht;
2541 }
2425 return NULL; 2542 return NULL;
2426 } 2543 }
2427 2544
2428 /* 2545 /*
2429 * Get the string value of a (global/local) variable. 2546 * Get the string value of a (global/local) variable.
2615 set_var( 2732 set_var(
2616 char_u *name, 2733 char_u *name,
2617 typval_T *tv, 2734 typval_T *tv,
2618 int copy) // make copy of value in "tv" 2735 int copy) // make copy of value in "tv"
2619 { 2736 {
2620 set_var_const(name, tv, copy, FALSE); 2737 set_var_const(name, NULL, tv, copy, 0);
2621 } 2738 }
2622 2739
2623 /* 2740 /*
2624 * Set variable "name" to value in "tv". 2741 * Set variable "name" to value in "tv".
2625 * If the variable already exists and "is_const" is FALSE the value is updated. 2742 * If the variable already exists and "is_const" is FALSE the value is updated.
2626 * Otherwise the variable is created. 2743 * Otherwise the variable is created.
2627 */ 2744 */
2628 void 2745 void
2629 set_var_const( 2746 set_var_const(
2630 char_u *name, 2747 char_u *name,
2748 type_T *type,
2631 typval_T *tv, 2749 typval_T *tv,
2632 int copy, // make copy of value in "tv" 2750 int copy, // make copy of value in "tv"
2633 int is_const) // disallow to modify existing variable 2751 int flags) // LET_IS_CONST and/or LET_NO_COMMAND
2634 { 2752 {
2635 dictitem_T *v; 2753 dictitem_T *di;
2636 char_u *varname; 2754 char_u *varname;
2637 hashtab_T *ht; 2755 hashtab_T *ht;
2756 int is_script_local;
2638 2757
2639 ht = find_var_ht(name, &varname); 2758 ht = find_var_ht(name, &varname);
2640 if (ht == NULL || *varname == NUL) 2759 if (ht == NULL || *varname == NUL)
2641 { 2760 {
2642 semsg(_(e_illvar), name); 2761 semsg(_(e_illvar), name);
2643 return; 2762 return;
2644 } 2763 }
2645 v = find_var_in_ht(ht, 0, varname, TRUE); 2764 is_script_local = ht == get_script_local_ht();
2765
2766 di = find_var_in_ht(ht, 0, varname, TRUE);
2646 2767
2647 // Search in parent scope which is possible to reference from lambda 2768 // Search in parent scope which is possible to reference from lambda
2648 if (v == NULL) 2769 if (di == NULL)
2649 v = find_var_in_scoped_ht(name, TRUE); 2770 di = find_var_in_scoped_ht(name, TRUE);
2650 2771
2651 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) 2772 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL)
2652 && var_check_func_name(name, v == NULL)) 2773 && var_check_func_name(name, di == NULL))
2653 return; 2774 return;
2654 2775
2655 if (v != NULL) 2776 if (di != NULL)
2656 { 2777 {
2657 if (is_const) 2778 if ((di->di_flags & DI_FLAGS_RELOAD) == 0)
2658 { 2779 {
2659 emsg(_(e_cannot_mod)); 2780 if (flags & LET_IS_CONST)
2660 return; 2781 {
2661 } 2782 emsg(_(e_cannot_mod));
2783 return;
2784 }
2785
2786 if (var_check_ro(di->di_flags, name, FALSE)
2787 || var_check_lock(di->di_tv.v_lock, name, FALSE))
2788 return;
2789
2790 if ((flags & LET_NO_COMMAND) == 0
2791 && is_script_local
2792 && current_sctx.sc_version == SCRIPT_VERSION_VIM9)
2793 {
2794 semsg(_("E1041: Redefining script item %s"), name);
2795 return;
2796 }
2797 }
2798 else
2799 // can only redefine once
2800 di->di_flags &= ~DI_FLAGS_RELOAD;
2662 2801
2663 // existing variable, need to clear the value 2802 // existing variable, need to clear the value
2664 if (var_check_ro(v->di_flags, name, FALSE) 2803
2665 || var_check_lock(v->di_tv.v_lock, name, FALSE)) 2804 // Handle setting internal di: variables separately where needed to
2666 return;
2667
2668 // Handle setting internal v: variables separately where needed to
2669 // prevent changing the type. 2805 // prevent changing the type.
2670 if (ht == &vimvarht) 2806 if (ht == &vimvarht)
2671 { 2807 {
2672 if (v->di_tv.v_type == VAR_STRING) 2808 if (di->di_tv.v_type == VAR_STRING)
2673 { 2809 {
2674 VIM_CLEAR(v->di_tv.vval.v_string); 2810 VIM_CLEAR(di->di_tv.vval.v_string);
2675 if (copy || tv->v_type != VAR_STRING) 2811 if (copy || tv->v_type != VAR_STRING)
2676 { 2812 {
2677 char_u *val = tv_get_string(tv); 2813 char_u *val = tv_get_string(tv);
2678 2814
2679 // Careful: when assigning to v:errmsg and tv_get_string() 2815 // Careful: when assigning to v:errmsg and tv_get_string()
2680 // causes an error message the variable will alrady be set. 2816 // causes an error message the variable will alrady be set.
2681 if (v->di_tv.vval.v_string == NULL) 2817 if (di->di_tv.vval.v_string == NULL)
2682 v->di_tv.vval.v_string = vim_strsave(val); 2818 di->di_tv.vval.v_string = vim_strsave(val);
2683 } 2819 }
2684 else 2820 else
2685 { 2821 {
2686 // Take over the string to avoid an extra alloc/free. 2822 // Take over the string to avoid an extra alloc/free.
2687 v->di_tv.vval.v_string = tv->vval.v_string; 2823 di->di_tv.vval.v_string = tv->vval.v_string;
2688 tv->vval.v_string = NULL; 2824 tv->vval.v_string = NULL;
2689 } 2825 }
2690 return; 2826 return;
2691 } 2827 }
2692 else if (v->di_tv.v_type == VAR_NUMBER) 2828 else if (di->di_tv.v_type == VAR_NUMBER)
2693 { 2829 {
2694 v->di_tv.vval.v_number = tv_get_number(tv); 2830 di->di_tv.vval.v_number = tv_get_number(tv);
2695 if (STRCMP(varname, "searchforward") == 0) 2831 if (STRCMP(varname, "searchforward") == 0)
2696 set_search_direction(v->di_tv.vval.v_number ? '/' : '?'); 2832 set_search_direction(di->di_tv.vval.v_number ? '/' : '?');
2697 #ifdef FEAT_SEARCH_EXTRA 2833 #ifdef FEAT_SEARCH_EXTRA
2698 else if (STRCMP(varname, "hlsearch") == 0) 2834 else if (STRCMP(varname, "hlsearch") == 0)
2699 { 2835 {
2700 no_hlsearch = !v->di_tv.vval.v_number; 2836 no_hlsearch = !di->di_tv.vval.v_number;
2701 redraw_all_later(SOME_VALID); 2837 redraw_all_later(SOME_VALID);
2702 } 2838 }
2703 #endif 2839 #endif
2704 return; 2840 return;
2705 } 2841 }
2706 else if (v->di_tv.v_type != tv->v_type) 2842 else if (di->di_tv.v_type != tv->v_type)
2707 { 2843 {
2708 semsg(_("E963: setting %s to value with wrong type"), name); 2844 semsg(_("E963: setting %s to value with wrong type"), name);
2709 return; 2845 return;
2710 } 2846 }
2711 } 2847 }
2712 2848
2713 clear_tv(&v->di_tv); 2849 clear_tv(&di->di_tv);
2714 } 2850 }
2715 else // add a new variable 2851 else // add a new variable
2716 { 2852 {
2717 // Can't add "v:" or "a:" variable. 2853 // Can't add "v:" or "a:" variable.
2718 if (ht == &vimvarht || ht == get_funccal_args_ht()) 2854 if (ht == &vimvarht || ht == get_funccal_args_ht())
2723 2859
2724 // Make sure the variable name is valid. 2860 // Make sure the variable name is valid.
2725 if (!valid_varname(varname)) 2861 if (!valid_varname(varname))
2726 return; 2862 return;
2727 2863
2728 v = alloc(sizeof(dictitem_T) + STRLEN(varname)); 2864 di = alloc(sizeof(dictitem_T) + STRLEN(varname));
2729 if (v == NULL) 2865 if (di == NULL)
2730 return; 2866 return;
2731 STRCPY(v->di_key, varname); 2867 STRCPY(di->di_key, varname);
2732 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 2868 if (hash_add(ht, DI2HIKEY(di)) == FAIL)
2733 { 2869 {
2734 vim_free(v); 2870 vim_free(di);
2735 return; 2871 return;
2736 } 2872 }
2737 v->di_flags = DI_FLAGS_ALLOC; 2873 di->di_flags = DI_FLAGS_ALLOC;
2738 if (is_const) 2874 if (flags & LET_IS_CONST)
2739 v->di_flags |= DI_FLAGS_LOCK; 2875 di->di_flags |= DI_FLAGS_LOCK;
2876
2877 if (is_script_local && current_sctx.sc_version == SCRIPT_VERSION_VIM9)
2878 {
2879 scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
2880
2881 // Store a pointer to the typval_T, so that it can be found by
2882 // index instead of using a hastab lookup.
2883 if (ga_grow(&si->sn_var_vals, 1) == OK)
2884 {
2885 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
2886 + si->sn_var_vals.ga_len;
2887 sv->sv_name = di->di_key;
2888 sv->sv_tv = &di->di_tv;
2889 sv->sv_type = type == NULL ? &t_any : type;
2890 sv->sv_const = (flags & LET_IS_CONST);
2891 sv->sv_export = is_export;
2892 ++si->sn_var_vals.ga_len;
2893
2894 // let ex_export() know the export worked.
2895 is_export = FALSE;
2896 }
2897 }
2740 } 2898 }
2741 2899
2742 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) 2900 if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT)
2743 copy_tv(tv, &v->di_tv); 2901 copy_tv(tv, &di->di_tv);
2744 else 2902 else
2745 { 2903 {
2746 v->di_tv = *tv; 2904 di->di_tv = *tv;
2747 v->di_tv.v_lock = 0; 2905 di->di_tv.v_lock = 0;
2748 init_tv(tv); 2906 init_tv(tv);
2749 } 2907 }
2750 2908
2751 if (is_const) 2909 if (flags & LET_IS_CONST)
2752 v->di_tv.v_lock |= VAR_LOCKED; 2910 di->di_tv.v_lock |= VAR_LOCKED;
2753 } 2911 }
2754 2912
2755 /* 2913 /*
2756 * Return TRUE if di_flags "flags" indicates variable "name" is read-only. 2914 * Return TRUE if di_flags "flags" indicates variable "name" is read-only.
2757 * Also give an error message. 2915 * Also give an error message.
3128 save_emsg = did_emsg; 3286 save_emsg = did_emsg;
3129 did_emsg = FALSE; 3287 did_emsg = FALSE;
3130 tv.v_type = VAR_STRING; 3288 tv.v_type = VAR_STRING;
3131 tv.vval.v_string = (char_u *)""; 3289 tv.vval.v_string = (char_u *)"";
3132 if (append) 3290 if (append)
3133 set_var_lval(redir_lval, redir_endp, &tv, TRUE, FALSE, (char_u *)"."); 3291 set_var_lval(redir_lval, redir_endp, &tv, TRUE, 0, (char_u *)".");
3134 else 3292 else
3135 set_var_lval(redir_lval, redir_endp, &tv, TRUE, FALSE, (char_u *)"="); 3293 set_var_lval(redir_lval, redir_endp, &tv, TRUE, 0, (char_u *)"=");
3136 clear_lval(redir_lval); 3294 clear_lval(redir_lval);
3137 err = did_emsg; 3295 err = did_emsg;
3138 did_emsg |= save_emsg; 3296 did_emsg |= save_emsg;
3139 if (err) 3297 if (err)
3140 { 3298 {
3203 // Call get_lval() again, if it's inside a Dict or List it may 3361 // Call get_lval() again, if it's inside a Dict or List it may
3204 // have changed. 3362 // have changed.
3205 redir_endp = get_lval(redir_varname, NULL, redir_lval, 3363 redir_endp = get_lval(redir_varname, NULL, redir_lval,
3206 FALSE, FALSE, 0, FNE_CHECK_START); 3364 FALSE, FALSE, 0, FNE_CHECK_START);
3207 if (redir_endp != NULL && redir_lval->ll_name != NULL) 3365 if (redir_endp != NULL && redir_lval->ll_name != NULL)
3208 set_var_lval(redir_lval, redir_endp, &tv, FALSE, FALSE, 3366 set_var_lval(redir_lval, redir_endp, &tv, FALSE, 0,
3209 (char_u *)"."); 3367 (char_u *)".");
3210 clear_lval(redir_lval); 3368 clear_lval(redir_lval);
3211 } 3369 }
3212 3370
3213 // free the collected output 3371 // free the collected output