Mercurial > vim
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;