diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-08-15 21:10:16 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-08-15 21:10:16 +0200 |
commit | 11107bab7ead9124f46a7ddf6aa3bb66b43a8246 (patch) | |
tree | 113c14273a2c908c44e38d0fde516aa682abd4b4 /src/vim9compile.c | |
parent | 3d1cde8a2f28dce2c82d2b2b4c5e35e6662030e0 (diff) | |
download | vim-git-11107bab7ead9124f46a7ddf6aa3bb66b43a8246.tar.gz |
patch 8.2.1462: Vim9: string slice not supported yetv8.2.1462
Problem: Vim9: string slice not supported yet.
Solution: Add support for string slicing.
Diffstat (limited to 'src/vim9compile.c')
-rw-r--r-- | src/vim9compile.c | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/src/vim9compile.c b/src/vim9compile.c index 11ffee9ad..c086c1cf8 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -3068,6 +3068,7 @@ compile_subscript( garray_T *stack = &cctx->ctx_type_stack; type_T **typep; vartype_T vtype; + int is_slice = FALSE; // list index: list[123] // dict member: dict[key] @@ -3082,11 +3083,36 @@ compile_subscript( *arg = skipwhite(p); if (may_get_next_line_error(p, arg, cctx) == FAIL) return FAIL; - if (compile_expr0(arg, cctx) == FAIL) - return FAIL; + if (**arg == ':') + // missing first index is equal to zero + generate_PUSHNR(cctx, 0); + else + { + if (compile_expr0(arg, cctx) == FAIL) + return FAIL; + if (may_get_next_line_error(p, arg, cctx) == FAIL) + return FAIL; + *arg = skipwhite(*arg); + } + if (**arg == ':') + { + *arg = skipwhite(*arg + 1); + if (may_get_next_line_error(p, arg, cctx) == FAIL) + return FAIL; + if (**arg == ']') + // missing second index is equal to end of string + generate_PUSHNR(cctx, -1); + else + { + if (compile_expr0(arg, cctx) == FAIL) + return FAIL; + if (may_get_next_line_error(p, arg, cctx) == FAIL) + return FAIL; + *arg = skipwhite(*arg); + } + is_slice = TRUE; + } - if (may_get_next_line_error(p, arg, cctx) == FAIL) - return FAIL; if (**arg != ']') { emsg(_(e_missbrac)); @@ -3098,7 +3124,8 @@ compile_subscript( // we can use the index value type. // TODO: If we don't know use an instruction to figure it out at // runtime. - typep = ((type_T **)stack->ga_data) + stack->ga_len - 2; + typep = ((type_T **)stack->ga_data) + stack->ga_len + - (is_slice ? 3 : 2); vtype = (*typep)->tt_type; if (*typep == &t_any) { @@ -3109,6 +3136,11 @@ compile_subscript( } if (vtype == VAR_DICT) { + if (is_slice) + { + emsg(_(e_cannot_slice_dictionary)); + return FAIL; + } if ((*typep)->tt_type == VAR_DICT) *typep = (*typep)->tt_member; else @@ -3124,12 +3156,24 @@ compile_subscript( } else if (vtype == VAR_STRING) { - *typep = &t_number; - if (generate_instr_drop(cctx, ISN_STRINDEX, 1) == FAIL) + *typep = &t_string; + if ((is_slice + ? generate_instr_drop(cctx, ISN_STRSLICE, 2) + : generate_instr_drop(cctx, ISN_STRINDEX, 1)) == FAIL) return FAIL; } + else if (vtype == VAR_BLOB) + { + emsg("Sorry, blob index and slice not implemented yet"); + return FAIL; + } else if (vtype == VAR_LIST || *typep == &t_any) { + if (is_slice) + { + emsg("Sorry, list slice not implemented yet"); + return FAIL; + } if ((*typep)->tt_type == VAR_LIST) *typep = (*typep)->tt_member; if (generate_instr_drop(cctx, ISN_LISTINDEX, 1) == FAIL) @@ -7052,6 +7096,7 @@ delete_instr(isn_T *isn) case ISN_FOR: case ISN_LISTINDEX: case ISN_STRINDEX: + case ISN_STRSLICE: case ISN_GETITEM: case ISN_SLICE: case ISN_MEMBER: |