Mercurial > vim
comparison src/vim9compile.c @ 21387:8d58cbb07a12 v8.2.1244
patch 8.2.1244: Vim9: in lambda index assumes a list
Commit: https://github.com/vim/vim/commit/6802cce407b8b181bcf3eafe701fa9f8a91f7a73
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jul 19 15:49:49 2020 +0200
patch 8.2.1244: Vim9: in lambda index assumes a list
Problem: Vim9: in lambda index assumes a list.
Solution: Use the value type to decide about list or dict. (closes https://github.com/vim/vim/issues/6479)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 19 Jul 2020 16:00:04 +0200 |
parents | 54a304e4dc57 |
children | 8b882afa8ed2 |
comparison
equal
deleted
inserted
replaced
21386:e29093c09d58 | 21387:8d58cbb07a12 |
---|---|
3746 } | 3746 } |
3747 else if (*p == '[') | 3747 else if (*p == '[') |
3748 { | 3748 { |
3749 garray_T *stack = &cctx->ctx_type_stack; | 3749 garray_T *stack = &cctx->ctx_type_stack; |
3750 type_T **typep; | 3750 type_T **typep; |
3751 vartype_T vtype; | |
3751 | 3752 |
3752 // list index: list[123] | 3753 // list index: list[123] |
3753 // dict member: dict[key] | 3754 // dict member: dict[key] |
3754 // TODO: blob index | 3755 // TODO: blob index |
3755 // TODO: more arguments | 3756 // TODO: more arguments |
3771 emsg(_(e_missbrac)); | 3772 emsg(_(e_missbrac)); |
3772 return FAIL; | 3773 return FAIL; |
3773 } | 3774 } |
3774 *arg = *arg + 1; | 3775 *arg = *arg + 1; |
3775 | 3776 |
3777 // We can index a list and a dict. If we don't know the type | |
3778 // we can use the index value type. | |
3779 // TODO: If we don't know use an instruction to figure it out at | |
3780 // runtime. | |
3776 typep = ((type_T **)stack->ga_data) + stack->ga_len - 2; | 3781 typep = ((type_T **)stack->ga_data) + stack->ga_len - 2; |
3777 if ((*typep)->tt_type == VAR_LIST || (*typep) == &t_any) | 3782 vtype = (*typep)->tt_type; |
3783 if (*typep == &t_any) | |
3784 { | |
3785 type_T *valtype = ((type_T **)stack->ga_data) | |
3786 [stack->ga_len - 1]; | |
3787 if (valtype == &t_string) | |
3788 vtype = VAR_DICT; | |
3789 } | |
3790 if (vtype == VAR_DICT) | |
3791 { | |
3792 if ((*typep)->tt_type == VAR_DICT) | |
3793 *typep = (*typep)->tt_member; | |
3794 else if (need_type(*typep, &t_dict_any, -2, cctx, FALSE) | |
3795 == FAIL) | |
3796 return FAIL; | |
3797 if (may_generate_2STRING(-1, cctx) == FAIL) | |
3798 return FAIL; | |
3799 if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL) | |
3800 return FAIL; | |
3801 } | |
3802 else if (vtype == VAR_LIST || *typep == &t_any) | |
3778 { | 3803 { |
3779 if ((*typep)->tt_type == VAR_LIST) | 3804 if ((*typep)->tt_type == VAR_LIST) |
3780 *typep = (*typep)->tt_member; | 3805 *typep = (*typep)->tt_member; |
3781 if (generate_instr_drop(cctx, ISN_INDEX, 1) == FAIL) | 3806 if (generate_instr_drop(cctx, ISN_INDEX, 1) == FAIL) |
3782 return FAIL; | |
3783 } | |
3784 else if ((*typep)->tt_type == VAR_DICT) | |
3785 { | |
3786 *typep = (*typep)->tt_member; | |
3787 if (may_generate_2STRING(-1, cctx) == FAIL) | |
3788 return FAIL; | |
3789 if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL) | |
3790 return FAIL; | 3807 return FAIL; |
3791 } | 3808 } |
3792 else | 3809 else |
3793 { | 3810 { |
3794 emsg(_(e_listdictblobreq)); | 3811 emsg(_(e_listdictblobreq)); |
5384 if (generate_GETITEM(cctx, var_idx) == FAIL) | 5401 if (generate_GETITEM(cctx, var_idx) == FAIL) |
5385 return FAIL; | 5402 return FAIL; |
5386 } | 5403 } |
5387 | 5404 |
5388 stacktype = stack->ga_len == 0 ? &t_void | 5405 stacktype = stack->ga_len == 0 ? &t_void |
5389 : ((type_T **)stack->ga_data)[stack->ga_len - 1]; | 5406 : ((type_T **)stack->ga_data)[stack->ga_len - 1]; |
5390 if (lvar != NULL && (is_decl || !has_type)) | 5407 if (lvar != NULL && (is_decl || !has_type)) |
5391 { | 5408 { |
5392 if (new_local && !has_type) | 5409 if (new_local && !has_type) |
5393 { | 5410 { |
5394 if (stacktype->tt_type == VAR_VOID) | 5411 if (stacktype->tt_type == VAR_VOID) |