diff src/vim9execute.c @ 20871:65d9189d4dca v8.2.0987

patch 8.2.0987: Vim9: cannot assign to [var; var] Commit: https://github.com/vim/vim/commit/9af78769eeae0318e07aa8b6af4d6e2244481ca7 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jun 16 11:34:42 2020 +0200 patch 8.2.0987: Vim9: cannot assign to [var; var] Problem: Vim9: cannot assign to [var; var]. Solution: Assign rest of items to a list.
author Bram Moolenaar <Bram@vim.org>
date Tue, 16 Jun 2020 11:45:04 +0200
parents 876e16c48bd1
children a3853794a768
line wrap: on
line diff
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -2114,6 +2114,35 @@ call_def_function(
 		}
 		break;
 
+	    case ISN_SLICE:
+		{
+		    list_T	*list;
+		    int		count = iptr->isn_arg.number;
+
+		    tv = STACK_TV_BOT(-1);
+		    if (tv->v_type != VAR_LIST)
+		    {
+			emsg(_(e_listreq));
+			goto failed;
+		    }
+		    list = tv->vval.v_list;
+
+		    // no error for short list, expect it to be checked earlier
+		    if (list != NULL && list->lv_len >= count)
+		    {
+			list_T	*newlist = list_slice(list,
+						      count, list->lv_len - 1);
+
+			if (newlist != NULL)
+			{
+			    list_unref(list);
+			    tv->vval.v_list = newlist;
+			    ++newlist->lv_refcount;
+			}
+		    }
+		}
+		break;
+
 	    case ISN_GETITEM:
 		{
 		    listitem_T	*li;
@@ -2243,6 +2272,25 @@ call_def_function(
 		}
 		break;
 
+	    case ISN_CHECKLEN:
+		{
+		    int	    min_len = iptr->isn_arg.checklen.cl_min_len;
+		    list_T  *list = NULL;
+
+		    tv = STACK_TV_BOT(-1);
+		    if (tv->v_type == VAR_LIST)
+			    list = tv->vval.v_list;
+		    if (list == NULL || list->lv_len < min_len
+			    || (list->lv_len > min_len
+					&& !iptr->isn_arg.checklen.cl_more_OK))
+		    {
+			semsg(_("E1093: Expected %d items but got %d"),
+				     min_len, list == NULL ? 0 : list->lv_len);
+			goto failed;
+		    }
+		}
+		break;
+
 	    case ISN_2BOOL:
 		{
 		    int n;
@@ -2814,6 +2862,8 @@ ex_disassemble(exarg_T *eap)
 	    // expression operations
 	    case ISN_CONCAT: smsg("%4d CONCAT", current); break;
 	    case ISN_INDEX: smsg("%4d INDEX", current); break;
+	    case ISN_SLICE: smsg("%4d SLICE %lld",
+					 current, iptr->isn_arg.number); break;
 	    case ISN_GETITEM: smsg("%4d ITEM %lld",
 					 current, iptr->isn_arg.number); break;
 	    case ISN_MEMBER: smsg("%4d MEMBER", current); break;
@@ -2826,6 +2876,10 @@ ex_disassemble(exarg_T *eap)
 				      vartype_name(iptr->isn_arg.type.ct_type),
 				      iptr->isn_arg.type.ct_off);
 				break;
+	    case ISN_CHECKLEN: smsg("%4d CHECKLEN %s%d", current,
+				iptr->isn_arg.checklen.cl_more_OK ? ">= " : "",
+				iptr->isn_arg.checklen.cl_min_len);
+			       break;
 	    case ISN_2BOOL: if (iptr->isn_arg.number)
 				smsg("%4d INVERT (!val)", current);
 			    else