Mercurial > vim
comparison src/vim9compile.c @ 25028:faa3de7aed8b v8.2.3051
patch 8.2.3051: Vim9: for loop with one list variable does not work
Commit: https://github.com/vim/vim/commit/444d878324525787e55185ce3c3e29a3de9b700a
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jun 26 12:40:56 2021 +0200
patch 8.2.3051: Vim9: for loop with one list variable does not work
Problem: Vim9: for loop with one list variable does not work.
Solution: Use a separate flag for unpacking a list. (closes https://github.com/vim/vim/issues/8452)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 26 Jun 2021 12:45:03 +0200 |
parents | 39551b6e0112 |
children | 214fddf4c765 |
comparison
equal
deleted
inserted
replaced
25027:ea3486f096df | 25028:faa3de7aed8b |
---|---|
7729 char_u *arg_end; | 7729 char_u *arg_end; |
7730 char_u *name = NULL; | 7730 char_u *name = NULL; |
7731 char_u *p; | 7731 char_u *p; |
7732 char_u *wp; | 7732 char_u *wp; |
7733 int var_count = 0; | 7733 int var_count = 0; |
7734 int var_list = FALSE; | |
7734 int semicolon = FALSE; | 7735 int semicolon = FALSE; |
7735 size_t varlen; | 7736 size_t varlen; |
7736 garray_T *stack = &cctx->ctx_type_stack; | 7737 garray_T *stack = &cctx->ctx_type_stack; |
7737 garray_T *instr = &cctx->ctx_instr; | 7738 garray_T *instr = &cctx->ctx_instr; |
7738 scope_T *scope; | 7739 scope_T *scope; |
7745 p = skip_var_list(arg_start, TRUE, &var_count, &semicolon, FALSE); | 7746 p = skip_var_list(arg_start, TRUE, &var_count, &semicolon, FALSE); |
7746 if (p == NULL) | 7747 if (p == NULL) |
7747 return NULL; | 7748 return NULL; |
7748 if (var_count == 0) | 7749 if (var_count == 0) |
7749 var_count = 1; | 7750 var_count = 1; |
7751 else | |
7752 var_list = TRUE; // can also be a list of one variable | |
7750 | 7753 |
7751 // consume "in" | 7754 // consume "in" |
7752 wp = p; | 7755 wp = p; |
7753 if (may_get_next_line_error(wp, &p, cctx) == FAIL) | 7756 if (may_get_next_line_error(wp, &p, cctx) == FAIL) |
7754 return NULL; | 7757 return NULL; |
7809 else if (vartype->tt_type == VAR_BLOB) | 7812 else if (vartype->tt_type == VAR_BLOB) |
7810 item_type = &t_number; | 7813 item_type = &t_number; |
7811 else if (vartype->tt_type == VAR_LIST | 7814 else if (vartype->tt_type == VAR_LIST |
7812 && vartype->tt_member->tt_type != VAR_ANY) | 7815 && vartype->tt_member->tt_type != VAR_ANY) |
7813 { | 7816 { |
7814 if (var_count == 1) | 7817 if (!var_list) |
7815 item_type = vartype->tt_member; | 7818 item_type = vartype->tt_member; |
7816 else if (vartype->tt_member->tt_type == VAR_LIST | 7819 else if (vartype->tt_member->tt_type == VAR_LIST |
7817 && vartype->tt_member->tt_member->tt_type != VAR_ANY) | 7820 && vartype->tt_member->tt_member->tt_type != VAR_ANY) |
7818 // TODO: should get the type for each lhs | 7821 // TODO: should get the type for each lhs |
7819 item_type = vartype->tt_member->tt_member; | 7822 item_type = vartype->tt_member->tt_member; |
7826 scope->se_u.se_for.fs_top_label = current_instr_idx(cctx); | 7829 scope->se_u.se_for.fs_top_label = current_instr_idx(cctx); |
7827 | 7830 |
7828 generate_FOR(cctx, loop_lvar->lv_idx); | 7831 generate_FOR(cctx, loop_lvar->lv_idx); |
7829 | 7832 |
7830 arg = arg_start; | 7833 arg = arg_start; |
7831 if (var_count > 1) | 7834 if (var_list) |
7832 { | 7835 { |
7833 generate_UNPACK(cctx, var_count, semicolon); | 7836 generate_UNPACK(cctx, var_count, semicolon); |
7834 arg = skipwhite(arg + 1); // skip white after '[' | 7837 arg = skipwhite(arg + 1); // skip white after '[' |
7835 | 7838 |
7836 // the list item is replaced by a number of items | 7839 // the list item is replaced by a number of items |
7897 semsg(_(e_cannot_declare_script_variable_in_function), name); | 7900 semsg(_(e_cannot_declare_script_variable_in_function), name); |
7898 goto failed; | 7901 goto failed; |
7899 } | 7902 } |
7900 | 7903 |
7901 // Reserve a variable to store "var". | 7904 // Reserve a variable to store "var". |
7902 where.wt_index = var_count > 1 ? idx + 1 : 0; | 7905 where.wt_index = var_list ? idx + 1 : 0; |
7903 where.wt_variable = TRUE; | 7906 where.wt_variable = TRUE; |
7904 if (lhs_type == &t_any) | 7907 if (lhs_type == &t_any) |
7905 lhs_type = item_type; | 7908 lhs_type = item_type; |
7906 else if (item_type != &t_unknown | 7909 else if (item_type != &t_unknown |
7907 && !(var_count > 1 && item_type == &t_any) | 7910 && !(var_list && item_type == &t_any) |
7908 && check_type(lhs_type, item_type, TRUE, where) == FAIL) | 7911 && check_type(lhs_type, item_type, TRUE, where) == FAIL) |
7909 goto failed; | 7912 goto failed; |
7910 var_lvar = reserve_local(cctx, arg, varlen, TRUE, lhs_type); | 7913 var_lvar = reserve_local(cctx, arg, varlen, TRUE, lhs_type); |
7911 if (var_lvar == NULL) | 7914 if (var_lvar == NULL) |
7912 // out of memory or used as an argument | 7915 // out of memory or used as an argument |