diff src/vim9execute.c @ 21826:ccad66ac6c3e v8.2.1462

patch 8.2.1462: Vim9: string slice not supported yet Commit: https://github.com/vim/vim/commit/11107bab7ead9124f46a7ddf6aa3bb66b43a8246 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Aug 15 21:10:16 2020 +0200 patch 8.2.1462: Vim9: string slice not supported yet Problem: Vim9: string slice not supported yet. Solution: Add support for string slicing.
author Bram Moolenaar <Bram@vim.org>
date Sat, 15 Aug 2020 21:15:04 +0200
parents b1f3d8a44ab6
children af5db9b6d210
line wrap: on
line diff
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -70,7 +70,7 @@ typedef struct {
 } ectx_T;
 
 // Get pointer to item relative to the bottom of the stack, -1 is the last one.
-#define STACK_TV_BOT(idx) (((typval_T *)ectx->ec_stack.ga_data) + ectx->ec_stack.ga_len + idx)
+#define STACK_TV_BOT(idx) (((typval_T *)ectx->ec_stack.ga_data) + ectx->ec_stack.ga_len + (idx))
 
     void
 to_string_error(vartype_T vartype)
@@ -2232,12 +2232,16 @@ call_def_function(
 		break;
 
 	    case ISN_STRINDEX:
+	    case ISN_STRSLICE:
 		{
-		    varnumber_T	n;
+		    int		is_slice = iptr->isn_type == ISN_STRSLICE;
+		    varnumber_T	n1 = 0, n2;
 		    char_u	*res;
 
 		    // string index: string is at stack-2, index at stack-1
-		    tv = STACK_TV_BOT(-2);
+		    // string slice: string is at stack-3, first index at
+		    // stack-2, second index at stack-1
+		    tv = is_slice ? STACK_TV_BOT(-3) : STACK_TV_BOT(-2);
 		    if (tv->v_type != VAR_STRING)
 		    {
 			SOURCING_LNUM = iptr->isn_lnum;
@@ -2245,6 +2249,18 @@ call_def_function(
 			goto on_error;
 		    }
 
+		    if (is_slice)
+		    {
+			tv = STACK_TV_BOT(-2);
+			if (tv->v_type != VAR_NUMBER)
+			{
+			    SOURCING_LNUM = iptr->isn_lnum;
+			    emsg(_(e_number_exp));
+			    goto on_error;
+			}
+			n1 = tv->vval.v_number;
+		    }
+
 		    tv = STACK_TV_BOT(-1);
 		    if (tv->v_type != VAR_NUMBER)
 		    {
@@ -2252,14 +2268,18 @@ call_def_function(
 			emsg(_(e_number_exp));
 			goto on_error;
 		    }
-		    n = tv->vval.v_number;
-
-		    // The resulting variable is a string of a single
-		    // character.  If the index is too big or negative the
-		    // result is empty.
-		    --ectx.ec_stack.ga_len;
+		    n2 = tv->vval.v_number;
+
+		    ectx.ec_stack.ga_len -= is_slice ? 2 : 1;
 		    tv = STACK_TV_BOT(-1);
-		    res = char_from_string(tv->vval.v_string, n);
+		    if (is_slice)
+			// Slice: Select the characters from the string
+			res = string_slice(tv->vval.v_string, n1, n2);
+		    else
+			// Index: The resulting variable is a string of a
+			// single character.  If the index is too big or
+			// negative the result is empty.
+			res = char_from_string(tv->vval.v_string, n2);
 		    vim_free(tv->vval.v_string);
 		    tv->vval.v_string = res;
 		}
@@ -3140,6 +3160,7 @@ ex_disassemble(exarg_T *eap)
 	    // expression operations
 	    case ISN_CONCAT: smsg("%4d CONCAT", current); break;
 	    case ISN_STRINDEX: smsg("%4d STRINDEX", current); break;
+	    case ISN_STRSLICE: smsg("%4d STRSLICE", current); break;
 	    case ISN_LISTINDEX: smsg("%4d LISTINDEX", current); break;
 	    case ISN_SLICE: smsg("%4d SLICE %lld",
 					 current, iptr->isn_arg.number); break;