diff src/evalvars.c @ 20091:a64c16ff98b8 v8.2.0601

patch 8.2.0601: Vim9: :unlet is not compiled Commit: https://github.com/vim/vim/commit/d72c1bf0a6784afdc8d8ceab4a007cd76d5b81e1 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Apr 19 16:28:59 2020 +0200 patch 8.2.0601: Vim9: :unlet is not compiled Problem: Vim9: :unlet is not compiled. Solution: Implement :unlet instruction and check for errors.
author Bram Moolenaar <Bram@vim.org>
date Sun, 19 Apr 2020 16:30:04 +0200
parents 04ef2ccf2519
children 646c53fa5781
line wrap: on
line diff
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -172,9 +172,8 @@ static void list_win_vars(int *first);
 static void list_tab_vars(int *first);
 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first);
 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int flags, char_u *endchars, char_u *op);
-static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep);
-static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit);
-static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock);
+static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep, void *cookie);
+static int do_lock_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep, void *cookie);
 static void item_lock(typval_T *tv, int deep, int lock);
 static void delete_var(hashtab_T *ht, hashitem_T *hi);
 static void list_one_var(dictitem_T *v, char *prefix, int *first);
@@ -1372,7 +1371,7 @@ ex_let_one(
     void
 ex_unlet(exarg_T *eap)
 {
-    ex_unletlock(eap, eap->arg, 0);
+    ex_unletlock(eap, eap->arg, 0, 0, do_unlet_var, NULL);
 }
 
 /*
@@ -1392,17 +1391,22 @@ ex_lockvar(exarg_T *eap)
 	arg = skipwhite(arg);
     }
 
-    ex_unletlock(eap, arg, deep);
+    ex_unletlock(eap, arg, deep, 0, do_lock_var, NULL);
 }
 
 /*
  * ":unlet", ":lockvar" and ":unlockvar" are quite similar.
+ * Also used for Vim9 script.  "callback" is invoked as:
+ *	callback(&lv, name_end, eap, deep, cookie)
  */
-    static void
+    void
 ex_unletlock(
     exarg_T	*eap,
     char_u	*argstart,
-    int		deep)
+    int		deep,
+    int		glv_flags,
+    int		(*callback)(lval_T *, char_u *, exarg_T *, int, void *),
+    void	*cookie)
 {
     char_u	*arg = argstart;
     char_u	*name_end;
@@ -1426,8 +1430,8 @@ ex_unletlock(
 	}
 
 	// Parse the name and find the end.
-	name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0,
-							     FNE_CHECK_START);
+	name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error,
+						   glv_flags, FNE_CHECK_START);
 	if (lv.ll_name == NULL)
 	    error = TRUE;	    // error but continue parsing
 	if (name_end == NULL || (!VIM_ISWHITE(*name_end)
@@ -1443,26 +1447,15 @@ ex_unletlock(
 	    break;
 	}
 
-	if (!error && !eap->skip)
-	{
-	    if (eap->cmdidx == CMD_unlet)
-	    {
-		if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL)
-		    error = TRUE;
-	    }
-	    else
-	    {
-		if (do_lock_var(&lv, name_end, deep,
-					  eap->cmdidx == CMD_lockvar) == FAIL)
-		    error = TRUE;
-	    }
-	}
+	if (!error && !eap->skip
+			 && callback(&lv, name_end, eap, deep, cookie) == FAIL)
+	    error = TRUE;
 
 	if (!eap->skip)
 	    clear_lval(&lv);
 
 	arg = skipwhite(name_end);
-    } while (!ends_excmd(*arg));
+    } while (!ends_excmd2(name_end, arg));
 
     eap->nextcmd = check_nextcmd(arg);
 }
@@ -1471,8 +1464,11 @@ ex_unletlock(
 do_unlet_var(
     lval_T	*lp,
     char_u	*name_end,
-    int		forceit)
+    exarg_T	*eap,
+    int		deep UNUSED,
+    void	*cookie UNUSED)
 {
+    int		forceit = eap->forceit;
     int		ret = OK;
     int		cc;
 
@@ -1541,6 +1537,10 @@ do_unlet(char_u *name, int forceit)
     dict_T	*d;
     dictitem_T	*di;
 
+    if (current_sctx.sc_version == SCRIPT_VERSION_VIM9
+	    && check_vim9_unlet(name) == FAIL)
+	return FAIL;
+
     ht = find_var_ht(name, &varname);
     if (ht != NULL && *varname != NUL)
     {
@@ -1592,9 +1592,11 @@ do_unlet(char_u *name, int forceit)
 do_lock_var(
     lval_T	*lp,
     char_u	*name_end,
+    exarg_T	*eap,
     int		deep,
-    int		lock)
+    void	*cookie UNUSED)
 {
+    int		lock = eap->cmdidx == CMD_lockvar;
     int		ret = OK;
     int		cc;
     dictitem_T	*di;