Mercurial > vim
comparison src/vim9execute.c @ 22975:a943b175586a v8.2.2034
patch 8.2.2034: Vim9: list unpack in for statement not compiled yet
Commit: https://github.com/vim/vim/commit/792f786aad8409ca9ab895392742643a5b6aed8f
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Nov 23 08:31:18 2020 +0100
patch 8.2.2034: Vim9: list unpack in for statement not compiled yet
Problem: Vim9: list unpack in for statement not compiled yet.
Solution: Compile list unpack. (closes https://github.com/vim/vim/issues/7345)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 23 Nov 2020 08:45:04 +0100 |
parents | 4c97c0747017 |
children | 1fa84623fc68 |
comparison
equal
deleted
inserted
replaced
22974:3f8025537dd9 | 22975:a943b175586a |
---|---|
2875 undo_cmdmod(&cmdmod); | 2875 undo_cmdmod(&cmdmod); |
2876 cmdmod = save_cmdmod; | 2876 cmdmod = save_cmdmod; |
2877 restore_cmdmod = FALSE; | 2877 restore_cmdmod = FALSE; |
2878 break; | 2878 break; |
2879 | 2879 |
2880 case ISN_UNPACK: | |
2881 { | |
2882 int count = iptr->isn_arg.unpack.unp_count; | |
2883 int semicolon = iptr->isn_arg.unpack.unp_semicolon; | |
2884 list_T *l; | |
2885 listitem_T *li; | |
2886 int i; | |
2887 | |
2888 // Check there is a valid list to unpack. | |
2889 tv = STACK_TV_BOT(-1); | |
2890 if (tv->v_type != VAR_LIST) | |
2891 { | |
2892 SOURCING_LNUM = iptr->isn_lnum; | |
2893 emsg(_(e_for_argument_must_be_sequence_of_lists)); | |
2894 goto on_error; | |
2895 } | |
2896 l = tv->vval.v_list; | |
2897 if (l == NULL | |
2898 || l->lv_len < (semicolon ? count - 1 : count)) | |
2899 { | |
2900 SOURCING_LNUM = iptr->isn_lnum; | |
2901 emsg(_(e_list_value_does_not_have_enough_items)); | |
2902 goto on_error; | |
2903 } | |
2904 else if (!semicolon && l->lv_len > count) | |
2905 { | |
2906 SOURCING_LNUM = iptr->isn_lnum; | |
2907 emsg(_(e_list_value_has_more_items_than_targets)); | |
2908 goto on_error; | |
2909 } | |
2910 | |
2911 CHECK_LIST_MATERIALIZE(l); | |
2912 if (GA_GROW(&ectx.ec_stack, count - 1) == FAIL) | |
2913 goto failed; | |
2914 ectx.ec_stack.ga_len += count - 1; | |
2915 | |
2916 // Variable after semicolon gets a list with the remaining | |
2917 // items. | |
2918 if (semicolon) | |
2919 { | |
2920 list_T *rem_list = | |
2921 list_alloc_with_items(l->lv_len - count + 1); | |
2922 | |
2923 if (rem_list == NULL) | |
2924 goto failed; | |
2925 tv = STACK_TV_BOT(-count); | |
2926 tv->vval.v_list = rem_list; | |
2927 ++rem_list->lv_refcount; | |
2928 tv->v_lock = 0; | |
2929 li = l->lv_first; | |
2930 for (i = 0; i < count - 1; ++i) | |
2931 li = li->li_next; | |
2932 for (i = 0; li != NULL; ++i) | |
2933 { | |
2934 list_set_item(rem_list, i, &li->li_tv); | |
2935 li = li->li_next; | |
2936 } | |
2937 --count; | |
2938 } | |
2939 | |
2940 // Produce the values in reverse order, first item last. | |
2941 li = l->lv_first; | |
2942 for (i = 0; i < count; ++i) | |
2943 { | |
2944 tv = STACK_TV_BOT(-i - 1); | |
2945 copy_tv(&li->li_tv, tv); | |
2946 li = li->li_next; | |
2947 } | |
2948 | |
2949 list_unref(l); | |
2950 } | |
2951 break; | |
2952 | |
2880 case ISN_SHUFFLE: | 2953 case ISN_SHUFFLE: |
2881 { | 2954 { |
2882 typval_T tmp_tv; | 2955 typval_T tmp_tv; |
2883 int item = iptr->isn_arg.shuffle.shfl_item; | 2956 int item = iptr->isn_arg.shuffle.shfl_item; |
2884 int up = iptr->isn_arg.shuffle.shfl_up; | 2957 int up = iptr->isn_arg.shuffle.shfl_up; |
2885 | 2958 |
2886 tmp_tv = *STACK_TV_BOT(-item); | 2959 tmp_tv = *STACK_TV_BOT(-item); |
2887 for ( ; up > 0 && item > 1; --up) | 2960 for ( ; up > 0 && item > 1; --up) |
2888 { | 2961 { |
2889 *STACK_TV_BOT(-item) = *STACK_TV_BOT(-item + 1); | 2962 *STACK_TV_BOT(-item) = *STACK_TV_BOT(-item + 1); |
3604 } | 3677 } |
3605 break; | 3678 break; |
3606 } | 3679 } |
3607 case ISN_CMDMOD_REV: smsg("%4d CMDMOD_REV", current); break; | 3680 case ISN_CMDMOD_REV: smsg("%4d CMDMOD_REV", current); break; |
3608 | 3681 |
3682 case ISN_UNPACK: smsg("%4d UNPACK %d%s", current, | |
3683 iptr->isn_arg.unpack.unp_count, | |
3684 iptr->isn_arg.unpack.unp_semicolon ? " semicolon" : ""); | |
3685 break; | |
3609 case ISN_SHUFFLE: smsg("%4d SHUFFLE %d up %d", current, | 3686 case ISN_SHUFFLE: smsg("%4d SHUFFLE %d up %d", current, |
3610 iptr->isn_arg.shuffle.shfl_item, | 3687 iptr->isn_arg.shuffle.shfl_item, |
3611 iptr->isn_arg.shuffle.shfl_up); | 3688 iptr->isn_arg.shuffle.shfl_up); |
3612 break; | 3689 break; |
3613 case ISN_DROP: smsg("%4d DROP", current); break; | 3690 case ISN_DROP: smsg("%4d DROP", current); break; |