Mercurial > vim
diff src/vim9execute.c @ 25591:ea69398b40d1 v8.2.3332
patch 8.2.3332: Vim9: cannot assign to range in list
Commit: https://github.com/vim/vim/commit/4f0884d6e24d1d45ec83fd86b372b403177d3298
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Aug 11 21:49:23 2021 +0200
patch 8.2.3332: Vim9: cannot assign to range in list
Problem: Vim9: cannot assign to range in list.
Solution: Implement overwriting a list range.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 11 Aug 2021 22:00:06 +0200 |
parents | 08a0abcb46c1 |
children | 6f13d9ea0d04 |
line wrap: on
line diff
--- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -2503,14 +2503,53 @@ exec_instructions(ectx_T *ectx) // -4 value to be stored // -3 first index or "none" // -2 second index or "none" - // -1 destination blob + // -1 destination list or blob tv = STACK_TV_BOT(-4); - if (tv_dest->v_type != VAR_BLOB) + if (tv_dest->v_type == VAR_LIST) { - status = FAIL; - emsg(_(e_blob_required)); + long n1; + long n2; + int error = FALSE; + + SOURCING_LNUM = iptr->isn_lnum; + n1 = (long)tv_get_number_chk(tv_idx1, &error); + if (error) + status = FAIL; + else + { + if (tv_idx2->v_type == VAR_SPECIAL + && tv_idx2->vval.v_number == VVAL_NONE) + n2 = list_len(tv_dest->vval.v_list) - 1; + else + n2 = (long)tv_get_number_chk(tv_idx2, &error); + if (error) + status = FAIL; + else + { + listitem_T *li1 = check_range_index_one( + tv_dest->vval.v_list, &n1, FALSE); + + if (li1 == NULL) + status = FAIL; + else + { + status = check_range_index_two( + tv_dest->vval.v_list, + &n1, li1, &n2, FALSE); + if (status != FAIL) + status = list_assign_range( + tv_dest->vval.v_list, + tv->vval.v_list, + n1, + n2, + tv_idx2->v_type == VAR_SPECIAL, + (char_u *)"=", + (char_u *)"[unknown]"); + } + } + } } - else + else if (tv_dest->v_type == VAR_BLOB) { varnumber_T n1; varnumber_T n2; @@ -2530,7 +2569,7 @@ exec_instructions(ectx_T *ectx) status = FAIL; else { - long bloblen = blob_len(tv_dest->vval.v_blob); + long bloblen = blob_len(tv_dest->vval.v_blob); if (check_blob_index(bloblen, n1, FALSE) == FAIL @@ -2543,6 +2582,11 @@ exec_instructions(ectx_T *ectx) } } } + else + { + status = FAIL; + emsg(_(e_blob_required)); + } clear_tv(tv_idx1); clear_tv(tv_idx2); @@ -5469,7 +5513,7 @@ list_instructions(char *pfx, isn_T *inst case ISN_ANYINDEX: smsg("%s%4d ANYINDEX", pfx, current); break; case ISN_ANYSLICE: smsg("%s%4d ANYSLICE", pfx, current); break; case ISN_SLICE: smsg("%s%4d SLICE %lld", - pfx, current, iptr->isn_arg.number); break; + pfx, current, iptr->isn_arg.number); break; case ISN_GETITEM: smsg("%s%4d ITEM %lld%s", pfx, current, iptr->isn_arg.getitem.gi_index, iptr->isn_arg.getitem.gi_with_op ? @@ -5490,7 +5534,8 @@ list_instructions(char *pfx, isn_T *inst type_name(ct->ct_type, &tofree), (int)ct->ct_off); else - smsg("%s%4d CHECKTYPE %s stack[%d] arg %d", pfx, current, + smsg("%s%4d CHECKTYPE %s stack[%d] arg %d", + pfx, current, type_name(ct->ct_type, &tofree), (int)ct->ct_off, (int)ct->ct_arg_idx);