comparison src/eval.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 2063b858cad9
children 6f13d9ea0d04
comparison
equal deleted inserted replaced
25590:db8dfe879ef8 25591:ea69398b40d1
43 blob_T *fi_blob; // blob being used 43 blob_T *fi_blob; // blob being used
44 char_u *fi_string; // copy of string being used 44 char_u *fi_string; // copy of string being used
45 int fi_byte_idx; // byte index in fi_string 45 int fi_byte_idx; // byte index in fi_string
46 } forinfo_T; 46 } forinfo_T;
47 47
48 static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op);
49 static int eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg); 48 static int eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
50 static int eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg); 49 static int eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
51 static int eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg); 50 static int eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
52 static int eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg); 51 static int eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
53 static int eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string); 52 static int eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int want_string);
825 int cc; 824 int cc;
826 dictitem_T *v; 825 dictitem_T *v;
827 typval_T var1; 826 typval_T var1;
828 typval_T var2; 827 typval_T var2;
829 int empty1 = FALSE; 828 int empty1 = FALSE;
830 listitem_T *ni;
831 char_u *key = NULL; 829 char_u *key = NULL;
832 int len; 830 int len;
833 hashtab_T *ht = NULL; 831 hashtab_T *ht = NULL;
834 int quiet = flags & GLV_QUIET; 832 int quiet = flags & GLV_QUIET;
835 int writing; 833 int writing;
1208 lp->ll_n1 = (long)tv_get_number(&var1); 1206 lp->ll_n1 = (long)tv_get_number(&var1);
1209 clear_tv(&var1); 1207 clear_tv(&var1);
1210 1208
1211 lp->ll_dict = NULL; 1209 lp->ll_dict = NULL;
1212 lp->ll_list = lp->ll_tv->vval.v_list; 1210 lp->ll_list = lp->ll_tv->vval.v_list;
1213 lp->ll_li = list_find_index(lp->ll_list, &lp->ll_n1); 1211 lp->ll_li = check_range_index_one(lp->ll_list, &lp->ll_n1, quiet);
1214 if (lp->ll_li == NULL) 1212 if (lp->ll_li == NULL)
1215 { 1213 {
1216 // Vim9: Allow for adding an item at the end. 1214 clear_tv(&var2);
1217 if (in_vim9script() && lp->ll_n1 == lp->ll_list->lv_len 1215 return NULL;
1218 && lp->ll_list->lv_lock == 0)
1219 {
1220 list_append_number(lp->ll_list, 0);
1221 lp->ll_li = list_find_index(lp->ll_list, &lp->ll_n1);
1222 }
1223 if (lp->ll_li == NULL)
1224 {
1225 clear_tv(&var2);
1226 if (!quiet)
1227 semsg(_(e_listidx), lp->ll_n1);
1228 return NULL;
1229 }
1230 } 1216 }
1231 1217
1232 if (lp->ll_valtype != NULL) 1218 if (lp->ll_valtype != NULL)
1233 // use the type of the member 1219 // use the type of the member
1234 lp->ll_valtype = lp->ll_valtype->tt_member; 1220 lp->ll_valtype = lp->ll_valtype->tt_member;
1242 if (lp->ll_range && !lp->ll_empty2) 1228 if (lp->ll_range && !lp->ll_empty2)
1243 { 1229 {
1244 lp->ll_n2 = (long)tv_get_number(&var2); 1230 lp->ll_n2 = (long)tv_get_number(&var2);
1245 // is number or string 1231 // is number or string
1246 clear_tv(&var2); 1232 clear_tv(&var2);
1247 if (lp->ll_n2 < 0) 1233 if (check_range_index_two(lp->ll_list,
1248 { 1234 &lp->ll_n1, lp->ll_li,
1249 ni = list_find(lp->ll_list, lp->ll_n2); 1235 &lp->ll_n2, quiet) == FAIL)
1250 if (ni == NULL)
1251 {
1252 if (!quiet)
1253 semsg(_(e_listidx), lp->ll_n2);
1254 return NULL;
1255 }
1256 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni);
1257 }
1258
1259 // Check that lp->ll_n2 isn't before lp->ll_n1.
1260 if (lp->ll_n1 < 0)
1261 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li);
1262 if (lp->ll_n2 < lp->ll_n1)
1263 {
1264 if (!quiet)
1265 semsg(_(e_listidx), lp->ll_n2);
1266 return NULL; 1236 return NULL;
1267 }
1268 } 1237 }
1269 1238
1270 lp->ll_tv = &lp->ll_li->li_tv; 1239 lp->ll_tv = &lp->ll_li->li_tv;
1271 } 1240 }
1272 } 1241 }
1301 int flags, // ASSIGN_CONST, ASSIGN_NO_DECL 1270 int flags, // ASSIGN_CONST, ASSIGN_NO_DECL
1302 char_u *op, 1271 char_u *op,
1303 int var_idx) // index for "let [a, b] = list" 1272 int var_idx) // index for "let [a, b] = list"
1304 { 1273 {
1305 int cc; 1274 int cc;
1306 listitem_T *ri;
1307 dictitem_T *di; 1275 dictitem_T *di;
1308 1276
1309 if (lp->ll_tv == NULL) 1277 if (lp->ll_tv == NULL)
1310 { 1278 {
1311 cc = *endp; 1279 cc = *endp;
1381 ? lp->ll_tv->v_lock 1349 ? lp->ll_tv->v_lock
1382 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE)) 1350 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE))
1383 ; 1351 ;
1384 else if (lp->ll_range) 1352 else if (lp->ll_range)
1385 { 1353 {
1386 listitem_T *ll_li = lp->ll_li;
1387 int ll_n1 = lp->ll_n1;
1388
1389 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) 1354 if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
1390 && (flags & ASSIGN_FOR_LOOP) == 0) 1355 && (flags & ASSIGN_FOR_LOOP) == 0)
1391 { 1356 {
1392 emsg(_("E996: Cannot lock a range")); 1357 emsg(_("E996: Cannot lock a range"));
1393 return; 1358 return;
1394 } 1359 }
1395 1360
1396 /* 1361 (void)list_assign_range(lp->ll_list, rettv->vval.v_list,
1397 * Check whether any of the list items is locked 1362 lp->ll_n1, lp->ll_n2, lp->ll_empty2, op, lp->ll_name);
1398 */
1399 for (ri = rettv->vval.v_list->lv_first; ri != NULL && ll_li != NULL; )
1400 {
1401 if (value_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE))
1402 return;
1403 ri = ri->li_next;
1404 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == ll_n1))
1405 break;
1406 ll_li = ll_li->li_next;
1407 ++ll_n1;
1408 }
1409
1410 /*
1411 * Assign the List values to the list items.
1412 */
1413 for (ri = rettv->vval.v_list->lv_first; ri != NULL; )
1414 {
1415 if (op != NULL && *op != '=')
1416 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op);
1417 else
1418 {
1419 clear_tv(&lp->ll_li->li_tv);
1420 copy_tv(&ri->li_tv, &lp->ll_li->li_tv);
1421 }
1422 ri = ri->li_next;
1423 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1))
1424 break;
1425 if (lp->ll_li->li_next == NULL)
1426 {
1427 // Need to add an empty item.
1428 if (list_append_number(lp->ll_list, 0) == FAIL)
1429 {
1430 ri = NULL;
1431 break;
1432 }
1433 }
1434 lp->ll_li = lp->ll_li->li_next;
1435 ++lp->ll_n1;
1436 }
1437 if (ri != NULL)
1438 emsg(_(e_list_value_has_more_items_than_targets));
1439 else if (lp->ll_empty2
1440 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL)
1441 : lp->ll_n1 != lp->ll_n2)
1442 emsg(_(e_list_value_does_not_have_enough_items));
1443 } 1363 }
1444 else 1364 else
1445 { 1365 {
1446 /* 1366 /*
1447 * Assign to a List or Dictionary item. 1367 * Assign to a List or Dictionary item.
1505 /* 1425 /*
1506 * Handle "tv1 += tv2", "tv1 -= tv2", "tv1 *= tv2", "tv1 /= tv2", "tv1 %= tv2" 1426 * Handle "tv1 += tv2", "tv1 -= tv2", "tv1 *= tv2", "tv1 /= tv2", "tv1 %= tv2"
1507 * and "tv1 .= tv2" 1427 * and "tv1 .= tv2"
1508 * Returns OK or FAIL. 1428 * Returns OK or FAIL.
1509 */ 1429 */
1510 static int 1430 int
1511 tv_op(typval_T *tv1, typval_T *tv2, char_u *op) 1431 tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
1512 { 1432 {
1513 varnumber_T n; 1433 varnumber_T n;
1514 char_u numbuf[NUMBUFLEN]; 1434 char_u numbuf[NUMBUFLEN];
1515 char_u *s; 1435 char_u *s;