diff src/vim9compile.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 23f5750146d9
children 1634ca41e4d3
line wrap: on
line diff
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1109,6 +1109,20 @@ generate_UNLET(cctx_T *cctx, isntype_T i
 }
 
 /*
+ * Generate an ISN_LOCKCONST instruction.
+ */
+    static int
+generate_LOCKCONST(cctx_T *cctx)
+{
+    isn_T	*isn;
+
+    RETURN_OK_IF_SKIP(cctx);
+    if ((isn = generate_instr(cctx, ISN_LOCKCONST)) == NULL)
+	return FAIL;
+    return OK;
+}
+
+/*
  * Generate an ISN_LOADS instruction.
  */
     static int
@@ -4342,7 +4356,7 @@ compile_nested_function(exarg_T *eap, cc
     ufunc_T	*ufunc;
     int		r;
 
-    if (*name_start == '!')
+    if (eap->forceit)
     {
 	emsg(_(e_cannot_use_bang_with_nested_def));
 	return NULL;
@@ -5232,6 +5246,11 @@ compile_assignment(char_u *arg, exarg_T 
 	}
 	else
 	{
+	    if (is_decl && eap->forceit && cmdidx == CMD_const
+		    && (dest == dest_script || dest == dest_local))
+		// ":const! var": lock the value, but not referenced variables
+		generate_LOCKCONST(cctx);
+
 	    switch (dest)
 	    {
 		case dest_option:
@@ -6362,13 +6381,8 @@ compile_put(char_u *arg, exarg_T *eap, c
     char_u	*line = arg;
     linenr_T	lnum;
     char	*errormsg;
-    int		above = FALSE;
-
-    if (*arg == '!')
-    {
-	above = TRUE;
-	line = skipwhite(arg + 1);
-    }
+    int		above = eap->forceit;
+
     eap->regname = *line;
 
     if (eap->regname == '=')
@@ -6411,7 +6425,7 @@ compile_exec(char_u *line, exarg_T *eap,
 
     if (eap->cmdidx >= 0 && eap->cmdidx < CMD_SIZE)
     {
-	long	argt = excmd_get_argt(eap->cmdidx);
+	long	argt = eap->argt;
 	int	usefilter = FALSE;
 
 	has_expr = argt & (EX_XFILE | EX_EXPAND);
@@ -6870,8 +6884,6 @@ compile_def_function(ufunc_T *ufunc, int
 	    }
 	}
 
-	p = skipwhite(p);
-
 	if (cctx.ctx_had_return
 		&& ea.cmdidx != CMD_elseif
 		&& ea.cmdidx != CMD_else
@@ -6886,6 +6898,18 @@ compile_def_function(ufunc_T *ufunc, int
 	    goto erret;
 	}
 
+	p = skipwhite(p);
+	if (ea.cmdidx != CMD_SIZE
+			    && ea.cmdidx != CMD_write && ea.cmdidx != CMD_read)
+	{
+	    ea.argt = excmd_get_argt(ea.cmdidx);
+	    if ((ea.argt & EX_BANG) && *p == '!')
+	    {
+		ea.forceit = TRUE;
+		p = skipwhite(p + 1);
+	    }
+	}
+
 	switch (ea.cmdidx)
 	{
 	    case CMD_def:
@@ -7309,6 +7333,7 @@ delete_instr(isn_T *isn)
 	case ISN_LOADTDICT:
 	case ISN_LOADV:
 	case ISN_LOADWDICT:
+	case ISN_LOCKCONST:
 	case ISN_MEMBER:
 	case ISN_NEGATENR:
 	case ISN_NEWDICT: