Mercurial > vim
comparison src/vim9compile.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 | d8fb5bb88362 |
children | c4e29355cd8b |
comparison
equal
deleted
inserted
replaced
25590:db8dfe879ef8 | 25591:ea69398b40d1 |
---|---|
6483 } | 6483 } |
6484 return OK; | 6484 return OK; |
6485 } | 6485 } |
6486 | 6486 |
6487 /* | 6487 /* |
6488 * Return TRUE if "lhs" has a range index: "[expr : expr]". | |
6489 */ | |
6490 static int | |
6491 has_list_index(char_u *idx_start, cctx_T *cctx) | |
6492 { | |
6493 char_u *p = idx_start; | |
6494 int save_skip; | |
6495 | |
6496 if (*p != '[') | |
6497 return FALSE; | |
6498 | |
6499 p = skipwhite(p + 1); | |
6500 if (*p == ':') | |
6501 return TRUE; | |
6502 | |
6503 save_skip = cctx->ctx_skip; | |
6504 cctx->ctx_skip = SKIP_YES; | |
6505 (void)compile_expr0(&p, cctx); | |
6506 cctx->ctx_skip = save_skip; | |
6507 return *skipwhite(p) == ':'; | |
6508 } | |
6509 | |
6510 /* | |
6488 * For an assignment with an index, compile the "idx" in "var[idx]" or "key" in | 6511 * For an assignment with an index, compile the "idx" in "var[idx]" or "key" in |
6489 * "var.key". | 6512 * "var.key". |
6490 */ | 6513 */ |
6491 static int | 6514 static int |
6492 compile_assign_index( | 6515 compile_assign_index( |
6650 garray_T *stack = &cctx->ctx_type_stack; | 6673 garray_T *stack = &cctx->ctx_type_stack; |
6651 int range = FALSE; | 6674 int range = FALSE; |
6652 | 6675 |
6653 if (compile_assign_index(var_start, lhs, &range, cctx) == FAIL) | 6676 if (compile_assign_index(var_start, lhs, &range, cctx) == FAIL) |
6654 return FAIL; | 6677 return FAIL; |
6655 if (is_assign && range && lhs->lhs_type != &t_blob | 6678 if (is_assign && range |
6656 && lhs->lhs_type != &t_any) | 6679 && lhs->lhs_type->tt_type != VAR_LIST |
6680 && lhs->lhs_type != &t_blob | |
6681 && lhs->lhs_type != &t_any) | |
6657 { | 6682 { |
6658 semsg(_(e_cannot_use_range_with_assignment_str), var_start); | 6683 semsg(_(e_cannot_use_range_with_assignment_str), var_start); |
6659 return FAIL; | 6684 return FAIL; |
6660 } | 6685 } |
6661 | 6686 |
7027 // Without operator check type here, otherwise below. | 7052 // Without operator check type here, otherwise below. |
7028 // Use the line number of the assignment. | 7053 // Use the line number of the assignment. |
7029 SOURCING_LNUM = start_lnum; | 7054 SOURCING_LNUM = start_lnum; |
7030 where.wt_index = var_count > 0 ? var_idx + 1 : 0; | 7055 where.wt_index = var_count > 0 ? var_idx + 1 : 0; |
7031 where.wt_variable = var_count > 0; | 7056 where.wt_variable = var_count > 0; |
7032 if (lhs.lhs_has_index) | 7057 // If assigning to a list or dict member, use the |
7058 // member type. Not for "list[:] =". | |
7059 if (lhs.lhs_has_index | |
7060 && !has_list_index(var_start + lhs.lhs_varlen, | |
7061 cctx)) | |
7033 use_type = lhs.lhs_member_type; | 7062 use_type = lhs.lhs_member_type; |
7034 if (need_type_where(rhs_type, use_type, -1, where, | 7063 if (need_type_where(rhs_type, use_type, -1, where, |
7035 cctx, FALSE, is_const) == FAIL) | 7064 cctx, FALSE, is_const) == FAIL) |
7036 goto theend; | 7065 goto theend; |
7037 } | 7066 } |