Mercurial > vim
comparison src/vim9execute.c @ 23517:36bf9a6fbd4c v8.2.2301
patch 8.2.2301: Vim9: cannot unlet a dict or list item
Commit: https://github.com/vim/vim/commit/752fc692ace51459cb407ec117c147b3bbebc071
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Jan 4 21:57:11 2021 +0100
patch 8.2.2301: Vim9: cannot unlet a dict or list item
Problem: Vim9: cannot unlet a dict or list item.
Solution: Add ISN_UNLETINDEX. Refactor assignment code to use for unlet.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 04 Jan 2021 22:00:04 +0100 |
parents | 872239543313 |
children | b0a6e7325169 |
comparison
equal
deleted
inserted
replaced
23516:4a8d345c230b | 23517:36bf9a6fbd4c |
---|---|
1781 vartype_T dest_type = iptr->isn_arg.vartype; | 1781 vartype_T dest_type = iptr->isn_arg.vartype; |
1782 typval_T *tv_idx = STACK_TV_BOT(-2); | 1782 typval_T *tv_idx = STACK_TV_BOT(-2); |
1783 typval_T *tv_dest = STACK_TV_BOT(-1); | 1783 typval_T *tv_dest = STACK_TV_BOT(-1); |
1784 int status = OK; | 1784 int status = OK; |
1785 | 1785 |
1786 // Stack contains: | |
1787 // -3 value to be stored | |
1788 // -2 index | |
1789 // -1 dict or list | |
1786 tv = STACK_TV_BOT(-3); | 1790 tv = STACK_TV_BOT(-3); |
1787 SOURCING_LNUM = iptr->isn_lnum; | 1791 SOURCING_LNUM = iptr->isn_lnum; |
1788 if (dest_type == VAR_ANY) | 1792 if (dest_type == VAR_ANY) |
1789 { | 1793 { |
1790 dest_type = tv_dest->v_type; | 1794 dest_type = tv_dest->v_type; |
1893 if (status == FAIL) | 1897 if (status == FAIL) |
1894 { | 1898 { |
1895 clear_tv(tv); | 1899 clear_tv(tv); |
1896 goto on_error; | 1900 goto on_error; |
1897 } | 1901 } |
1902 } | |
1903 break; | |
1904 | |
1905 // unlet item in list or dict variable | |
1906 case ISN_UNLETINDEX: | |
1907 { | |
1908 typval_T *tv_idx = STACK_TV_BOT(-2); | |
1909 typval_T *tv_dest = STACK_TV_BOT(-1); | |
1910 int status = OK; | |
1911 | |
1912 // Stack contains: | |
1913 // -2 index | |
1914 // -1 dict or list | |
1915 if (tv_dest->v_type == VAR_DICT) | |
1916 { | |
1917 // unlet a dict item, index must be a string | |
1918 if (tv_idx->v_type != VAR_STRING) | |
1919 { | |
1920 semsg(_(e_expected_str_but_got_str), | |
1921 vartype_name(VAR_STRING), | |
1922 vartype_name(tv_idx->v_type)); | |
1923 status = FAIL; | |
1924 } | |
1925 else | |
1926 { | |
1927 dict_T *d = tv_dest->vval.v_dict; | |
1928 char_u *key = tv_idx->vval.v_string; | |
1929 dictitem_T *di = NULL; | |
1930 | |
1931 if (key == NULL) | |
1932 key = (char_u *)""; | |
1933 if (d != NULL) | |
1934 di = dict_find(d, key, (int)STRLEN(key)); | |
1935 if (di == NULL) | |
1936 { | |
1937 // NULL dict is equivalent to empty dict | |
1938 semsg(_(e_dictkey), key); | |
1939 status = FAIL; | |
1940 } | |
1941 else | |
1942 { | |
1943 // TODO: check for dict or item locked | |
1944 dictitem_remove(d, di); | |
1945 } | |
1946 } | |
1947 } | |
1948 else if (tv_dest->v_type == VAR_LIST) | |
1949 { | |
1950 // unlet a List item, index must be a number | |
1951 if (tv_idx->v_type != VAR_NUMBER) | |
1952 { | |
1953 semsg(_(e_expected_str_but_got_str), | |
1954 vartype_name(VAR_NUMBER), | |
1955 vartype_name(tv_idx->v_type)); | |
1956 status = FAIL; | |
1957 } | |
1958 else | |
1959 { | |
1960 list_T *l = tv_dest->vval.v_list; | |
1961 varnumber_T n = tv_idx->vval.v_number; | |
1962 listitem_T *li = NULL; | |
1963 | |
1964 li = list_find(l, n); | |
1965 if (li == NULL) | |
1966 { | |
1967 semsg(_(e_listidx), n); | |
1968 status = FAIL; | |
1969 } | |
1970 else | |
1971 // TODO: check for list or item locked | |
1972 listitem_remove(l, li); | |
1973 } | |
1974 } | |
1975 else | |
1976 { | |
1977 status = FAIL; | |
1978 semsg(_(e_cannot_index_str), | |
1979 vartype_name(tv_dest->v_type)); | |
1980 } | |
1981 | |
1982 clear_tv(tv_idx); | |
1983 clear_tv(tv_dest); | |
1984 ectx.ec_stack.ga_len -= 2; | |
1985 if (status == FAIL) | |
1986 goto on_error; | |
1898 } | 1987 } |
1899 break; | 1988 break; |
1900 | 1989 |
1901 // push constant | 1990 // push constant |
1902 case ISN_PUSHNR: | 1991 case ISN_PUSHNR: |
3647 case ISN_UNLETENV: | 3736 case ISN_UNLETENV: |
3648 smsg("%4d UNLETENV%s $%s", current, | 3737 smsg("%4d UNLETENV%s $%s", current, |
3649 iptr->isn_arg.unlet.ul_forceit ? "!" : "", | 3738 iptr->isn_arg.unlet.ul_forceit ? "!" : "", |
3650 iptr->isn_arg.unlet.ul_name); | 3739 iptr->isn_arg.unlet.ul_name); |
3651 break; | 3740 break; |
3741 case ISN_UNLETINDEX: | |
3742 smsg("%4d UNLETINDEX", current); | |
3743 break; | |
3652 case ISN_LOCKCONST: | 3744 case ISN_LOCKCONST: |
3653 smsg("%4d LOCKCONST", current); | 3745 smsg("%4d LOCKCONST", current); |
3654 break; | 3746 break; |
3655 case ISN_NEWLIST: | 3747 case ISN_NEWLIST: |
3656 smsg("%4d NEWLIST size %lld", current, | 3748 smsg("%4d NEWLIST size %lld", current, |