diff src/vim9execute.c @ 22272:eb1f5f618c75 v8.2.1685

patch 8.2.1685: Vim9: cannot declare a constant value Commit: https://github.com/vim/vim/commit/0b4c66c67a083f25816b9cdb8e76a41e02d9f560 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Sep 14 21:39:44 2020 +0200 patch 8.2.1685: Vim9: cannot declare a constant value Problem: Vim9: cannot declare a constant value. Solution: Introduce ":const!".
author Bram Moolenaar <Bram@vim.org>
date Mon, 14 Sep 2020 21:45:04 +0200
parents 3f082bd15d29
children 6b385c2b9ff5
line wrap: on
line diff
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -678,6 +678,21 @@ call_partial(typval_T *tv, int argcount_
 }
 
 /*
+ * Check if "lock" is VAR_LOCKED or VAR_FIXED.  If so give an error and return
+ * TRUE.
+ */
+    static int
+error_if_locked(int lock, char *error)
+{
+    if (lock & (VAR_LOCKED | VAR_FIXED))
+    {
+	emsg(_(error));
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
  * Store "tv" in variable "name".
  * This is for s: and g: variables.
  */
@@ -1455,12 +1470,12 @@ call_def_function(
 		    typval_T	*tv_list = STACK_TV_BOT(-1);
 		    list_T	*list = tv_list->vval.v_list;
 
+		    SOURCING_LNUM = iptr->isn_lnum;
 		    if (lidx < 0 && list->lv_len + lidx >= 0)
 			// negative index is relative to the end
 			lidx = list->lv_len + lidx;
 		    if (lidx < 0 || lidx > list->lv_len)
 		    {
-			SOURCING_LNUM = iptr->isn_lnum;
 			semsg(_(e_listidx), lidx);
 			goto on_error;
 		    }
@@ -1469,12 +1484,18 @@ call_def_function(
 		    {
 			listitem_T *li = list_find(list, lidx);
 
+			if (error_if_locked(li->li_tv.v_lock,
+						    e_cannot_change_list_item))
+			    goto failed;
 			// overwrite existing list item
 			clear_tv(&li->li_tv);
 			li->li_tv = *tv;
 		    }
 		    else
 		    {
+			if (error_if_locked(list->lv_lock,
+							 e_cannot_change_list))
+			    goto failed;
 			// append to list, only fails when out of memory
 			if (list_append_tv(list, tv) == FAIL)
 			    goto failed;
@@ -1495,9 +1516,9 @@ call_def_function(
 		    dict_T	*dict = tv_dict->vval.v_dict;
 		    dictitem_T	*di;
 
+		    SOURCING_LNUM = iptr->isn_lnum;
 		    if (dict == NULL)
 		    {
-			SOURCING_LNUM = iptr->isn_lnum;
 			emsg(_(e_dictionary_not_set));
 			goto on_error;
 		    }
@@ -1507,12 +1528,18 @@ call_def_function(
 		    di = dict_find(dict, key, -1);
 		    if (di != NULL)
 		    {
+			if (error_if_locked(di->di_tv.v_lock,
+						    e_cannot_change_dict_item))
+			    goto failed;
 			// overwrite existing value
 			clear_tv(&di->di_tv);
 			di->di_tv = *tv;
 		    }
 		    else
 		    {
+			if (error_if_locked(dict->dv_lock,
+							 e_cannot_change_dict))
+			    goto failed;
 			// add to dict, only fails when out of memory
 			if (dict_add_tv(dict, (char *)key, tv) == FAIL)
 			    goto failed;
@@ -1603,6 +1630,10 @@ call_def_function(
 		vim_unsetenv(iptr->isn_arg.unlet.ul_name);
 		break;
 
+	    case ISN_LOCKCONST:
+		item_lock(STACK_TV_BOT(-1), 100, TRUE, TRUE);
+		break;
+
 	    // create a list from items on the stack; uses a single allocation
 	    // for the list header and the items
 	    case ISN_NEWLIST:
@@ -3025,6 +3056,9 @@ ex_disassemble(exarg_T *eap)
 			iptr->isn_arg.unlet.ul_forceit ? "!" : "",
 			iptr->isn_arg.unlet.ul_name);
 		break;
+	    case ISN_LOCKCONST:
+		smsg("%4d LOCKCONST", current);
+		break;
 	    case ISN_NEWLIST:
 		smsg("%4d NEWLIST size %lld", current,
 					    (long long)(iptr->isn_arg.number));