diff src/eval.c @ 28002:1012048eed26 v8.2.4526

patch 8.2.4526: Vim9: cannot set variables to a null value Commit: https://github.com/vim/vim/commit/8acb9cc6209768ca7ec75c9f7af8c389312ea8d6 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Mar 8 13:18:55 2022 +0000 patch 8.2.4526: Vim9: cannot set variables to a null value Problem: Vim9: cannot set variables to a null value. Solution: Add null_list, null_job, etc.
author Bram Moolenaar <Bram@vim.org>
date Tue, 08 Mar 2022 14:30:05 +0100
parents 3813036f19cb
children 4aa79224acd2
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -943,6 +943,7 @@ get_lval(
 		    type_list = &SCRIPT_ITEM(current_sctx.sc_sid)->sn_type_list;
 		else
 		{
+		    // TODO: should we give an error here?
 		    type_list = &tmp_type_list;
 		    ga_init2(type_list, sizeof(type_T), 10);
 		}
@@ -3483,6 +3484,100 @@ eval_leader(char_u **arg, int vim9)
 }
 
 /*
+ * Check for a predefined value "true", "false" and "null.*".
+ * Return OK when recognized.
+ */
+    int
+handle_predefined(char_u *s, int len, typval_T *rettv)
+{
+    switch (len)
+    {
+	case 4: if (STRNCMP(s, "true", 4) == 0)
+		{
+		    rettv->v_type = VAR_BOOL;
+		    rettv->vval.v_number = VVAL_TRUE;
+		    return OK;
+		}
+		if (STRNCMP(s, "null", 4) == 0)
+		{
+		    rettv->v_type = VAR_SPECIAL;
+		    rettv->vval.v_number = VVAL_NULL;
+		    return OK;
+		}
+		break;
+	case 5: if (STRNCMP(s, "false", 5) == 0)
+		{
+		    rettv->v_type = VAR_BOOL;
+		    rettv->vval.v_number = VVAL_FALSE;
+		    return OK;
+		}
+		break;
+#ifdef FEAT_JOB_CHANNEL
+	case 8: if (STRNCMP(s, "null_job", 8) == 0)
+		{
+		    rettv->v_type = VAR_JOB;
+		    rettv->vval.v_job = NULL;
+		    return OK;
+		}
+		break;
+#endif
+	case 9:
+		if (STRNCMP(s, "null_", 5) != 0)
+		    break;
+		if (STRNCMP(s + 5, "list", 4) == 0)
+		{
+		    rettv->v_type = VAR_LIST;
+		    rettv->vval.v_list = NULL;
+		    return OK;
+		}
+		if (STRNCMP(s + 5, "dict", 4) == 0)
+		{
+		    rettv->v_type = VAR_DICT;
+		    rettv->vval.v_dict = NULL;
+		    return OK;
+		}
+		if (STRNCMP(s + 5, "blob", 4) == 0)
+		{
+		    rettv->v_type = VAR_BLOB;
+		    rettv->vval.v_blob = NULL;
+		    return OK;
+		}
+		break;
+	case 11: if (STRNCMP(s, "null_string", 11) == 0)
+		{
+		    rettv->v_type = VAR_STRING;
+		    rettv->vval.v_string = NULL;
+		    return OK;
+		}
+		break;
+	case 12:
+#ifdef FEAT_JOB_CHANNEL
+		if (STRNCMP(s, "null_channel", 12) == 0)
+		{
+		    rettv->v_type = VAR_CHANNEL;
+		    rettv->vval.v_channel = NULL;
+		    return OK;
+		}
+#endif
+		if (STRNCMP(s, "null_partial", 12) == 0)
+		{
+		    rettv->v_type = VAR_PARTIAL;
+		    rettv->vval.v_partial = NULL;
+		    return OK;
+		}
+		break;
+	case 13: if (STRNCMP(s, "null_function", 13) == 0)
+		{
+		    rettv->v_type = VAR_FUNC;
+		    rettv->vval.v_string = NULL;
+		    return OK;
+		}
+		break;
+    }
+    return FAIL;
+}
+
+/*
  * Handle sixth level expression:
  *  number		number constant
  *  0zFFFFFFFF		Blob constant
@@ -3757,26 +3852,11 @@ eval7(
 		ret = FAIL;
 	    else if (evaluate)
 	    {
-		// get the value of "true", "false" or a variable
-		if (len == 4 && vim9script && STRNCMP(s, "true", 4) == 0)
-		{
-		    rettv->v_type = VAR_BOOL;
-		    rettv->vval.v_number = VVAL_TRUE;
-		    ret = OK;
-		}
-		else if (len == 5 && vim9script && STRNCMP(s, "false", 5) == 0)
-		{
-		    rettv->v_type = VAR_BOOL;
-		    rettv->vval.v_number = VVAL_FALSE;
-		    ret = OK;
-		}
-		else if (len == 4 && vim9script && STRNCMP(s, "null", 4) == 0)
-		{
-		    rettv->v_type = VAR_SPECIAL;
-		    rettv->vval.v_number = VVAL_NULL;
-		    ret = OK;
-		}
-		else
+		// get the value of "true", "false", etc. or a variable
+		ret = FAIL;
+		if (vim9script)
+		    ret = handle_predefined(s, len, rettv);
+		if (ret == FAIL)
 		{
 		    name_start = s;
 		    ret = eval_variable(s, len, 0, rettv, NULL,