Mercurial > vim
comparison src/vim9execute.c @ 22272:eb1f5f618c75 v8.2.1685
patch 8.2.1685: Vim9: cannot declare a constant value
Commit: https://github.com/vim/vim/commit/0b4c66c67a083f25816b9cdb8e76a41e02d9f560
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Sep 14 21:39:44 2020 +0200
patch 8.2.1685: Vim9: cannot declare a constant value
Problem: Vim9: cannot declare a constant value.
Solution: Introduce ":const!".
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 14 Sep 2020 21:45:04 +0200 |
parents | 3f082bd15d29 |
children | 6b385c2b9ff5 |
comparison
equal
deleted
inserted
replaced
22271:0440d470ae70 | 22272:eb1f5f618c75 |
---|---|
676 } | 676 } |
677 return OK; | 677 return OK; |
678 } | 678 } |
679 | 679 |
680 /* | 680 /* |
681 * Check if "lock" is VAR_LOCKED or VAR_FIXED. If so give an error and return | |
682 * TRUE. | |
683 */ | |
684 static int | |
685 error_if_locked(int lock, char *error) | |
686 { | |
687 if (lock & (VAR_LOCKED | VAR_FIXED)) | |
688 { | |
689 emsg(_(error)); | |
690 return TRUE; | |
691 } | |
692 return FALSE; | |
693 } | |
694 | |
695 /* | |
681 * Store "tv" in variable "name". | 696 * Store "tv" in variable "name". |
682 * This is for s: and g: variables. | 697 * This is for s: and g: variables. |
683 */ | 698 */ |
684 static void | 699 static void |
685 store_var(char_u *name, typval_T *tv) | 700 store_var(char_u *name, typval_T *tv) |
1453 typval_T *tv_idx = STACK_TV_BOT(-2); | 1468 typval_T *tv_idx = STACK_TV_BOT(-2); |
1454 varnumber_T lidx = tv_idx->vval.v_number; | 1469 varnumber_T lidx = tv_idx->vval.v_number; |
1455 typval_T *tv_list = STACK_TV_BOT(-1); | 1470 typval_T *tv_list = STACK_TV_BOT(-1); |
1456 list_T *list = tv_list->vval.v_list; | 1471 list_T *list = tv_list->vval.v_list; |
1457 | 1472 |
1473 SOURCING_LNUM = iptr->isn_lnum; | |
1458 if (lidx < 0 && list->lv_len + lidx >= 0) | 1474 if (lidx < 0 && list->lv_len + lidx >= 0) |
1459 // negative index is relative to the end | 1475 // negative index is relative to the end |
1460 lidx = list->lv_len + lidx; | 1476 lidx = list->lv_len + lidx; |
1461 if (lidx < 0 || lidx > list->lv_len) | 1477 if (lidx < 0 || lidx > list->lv_len) |
1462 { | 1478 { |
1463 SOURCING_LNUM = iptr->isn_lnum; | |
1464 semsg(_(e_listidx), lidx); | 1479 semsg(_(e_listidx), lidx); |
1465 goto on_error; | 1480 goto on_error; |
1466 } | 1481 } |
1467 tv = STACK_TV_BOT(-3); | 1482 tv = STACK_TV_BOT(-3); |
1468 if (lidx < list->lv_len) | 1483 if (lidx < list->lv_len) |
1469 { | 1484 { |
1470 listitem_T *li = list_find(list, lidx); | 1485 listitem_T *li = list_find(list, lidx); |
1471 | 1486 |
1487 if (error_if_locked(li->li_tv.v_lock, | |
1488 e_cannot_change_list_item)) | |
1489 goto failed; | |
1472 // overwrite existing list item | 1490 // overwrite existing list item |
1473 clear_tv(&li->li_tv); | 1491 clear_tv(&li->li_tv); |
1474 li->li_tv = *tv; | 1492 li->li_tv = *tv; |
1475 } | 1493 } |
1476 else | 1494 else |
1477 { | 1495 { |
1496 if (error_if_locked(list->lv_lock, | |
1497 e_cannot_change_list)) | |
1498 goto failed; | |
1478 // append to list, only fails when out of memory | 1499 // append to list, only fails when out of memory |
1479 if (list_append_tv(list, tv) == FAIL) | 1500 if (list_append_tv(list, tv) == FAIL) |
1480 goto failed; | 1501 goto failed; |
1481 clear_tv(tv); | 1502 clear_tv(tv); |
1482 } | 1503 } |
1493 char_u *key = tv_key->vval.v_string; | 1514 char_u *key = tv_key->vval.v_string; |
1494 typval_T *tv_dict = STACK_TV_BOT(-1); | 1515 typval_T *tv_dict = STACK_TV_BOT(-1); |
1495 dict_T *dict = tv_dict->vval.v_dict; | 1516 dict_T *dict = tv_dict->vval.v_dict; |
1496 dictitem_T *di; | 1517 dictitem_T *di; |
1497 | 1518 |
1519 SOURCING_LNUM = iptr->isn_lnum; | |
1498 if (dict == NULL) | 1520 if (dict == NULL) |
1499 { | 1521 { |
1500 SOURCING_LNUM = iptr->isn_lnum; | |
1501 emsg(_(e_dictionary_not_set)); | 1522 emsg(_(e_dictionary_not_set)); |
1502 goto on_error; | 1523 goto on_error; |
1503 } | 1524 } |
1504 if (key == NULL) | 1525 if (key == NULL) |
1505 key = (char_u *)""; | 1526 key = (char_u *)""; |
1506 tv = STACK_TV_BOT(-3); | 1527 tv = STACK_TV_BOT(-3); |
1507 di = dict_find(dict, key, -1); | 1528 di = dict_find(dict, key, -1); |
1508 if (di != NULL) | 1529 if (di != NULL) |
1509 { | 1530 { |
1531 if (error_if_locked(di->di_tv.v_lock, | |
1532 e_cannot_change_dict_item)) | |
1533 goto failed; | |
1510 // overwrite existing value | 1534 // overwrite existing value |
1511 clear_tv(&di->di_tv); | 1535 clear_tv(&di->di_tv); |
1512 di->di_tv = *tv; | 1536 di->di_tv = *tv; |
1513 } | 1537 } |
1514 else | 1538 else |
1515 { | 1539 { |
1540 if (error_if_locked(dict->dv_lock, | |
1541 e_cannot_change_dict)) | |
1542 goto failed; | |
1516 // add to dict, only fails when out of memory | 1543 // add to dict, only fails when out of memory |
1517 if (dict_add_tv(dict, (char *)key, tv) == FAIL) | 1544 if (dict_add_tv(dict, (char *)key, tv) == FAIL) |
1518 goto failed; | 1545 goto failed; |
1519 clear_tv(tv); | 1546 clear_tv(tv); |
1520 } | 1547 } |
1601 break; | 1628 break; |
1602 case ISN_UNLETENV: | 1629 case ISN_UNLETENV: |
1603 vim_unsetenv(iptr->isn_arg.unlet.ul_name); | 1630 vim_unsetenv(iptr->isn_arg.unlet.ul_name); |
1604 break; | 1631 break; |
1605 | 1632 |
1633 case ISN_LOCKCONST: | |
1634 item_lock(STACK_TV_BOT(-1), 100, TRUE, TRUE); | |
1635 break; | |
1636 | |
1606 // create a list from items on the stack; uses a single allocation | 1637 // create a list from items on the stack; uses a single allocation |
1607 // for the list header and the items | 1638 // for the list header and the items |
1608 case ISN_NEWLIST: | 1639 case ISN_NEWLIST: |
1609 if (exe_newlist(iptr->isn_arg.number, &ectx) == FAIL) | 1640 if (exe_newlist(iptr->isn_arg.number, &ectx) == FAIL) |
1610 goto failed; | 1641 goto failed; |
3022 break; | 3053 break; |
3023 case ISN_UNLETENV: | 3054 case ISN_UNLETENV: |
3024 smsg("%4d UNLETENV%s $%s", current, | 3055 smsg("%4d UNLETENV%s $%s", current, |
3025 iptr->isn_arg.unlet.ul_forceit ? "!" : "", | 3056 iptr->isn_arg.unlet.ul_forceit ? "!" : "", |
3026 iptr->isn_arg.unlet.ul_name); | 3057 iptr->isn_arg.unlet.ul_name); |
3058 break; | |
3059 case ISN_LOCKCONST: | |
3060 smsg("%4d LOCKCONST", current); | |
3027 break; | 3061 break; |
3028 case ISN_NEWLIST: | 3062 case ISN_NEWLIST: |
3029 smsg("%4d NEWLIST size %lld", current, | 3063 smsg("%4d NEWLIST size %lld", current, |
3030 (long long)(iptr->isn_arg.number)); | 3064 (long long)(iptr->isn_arg.number)); |
3031 break; | 3065 break; |