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