# HG changeset patch # User Bram Moolenaar # Date 1620328504 -7200 # Node ID 033b435701405a3eccae6386c3880cfae612be51 # Parent 244ecababf007f6e751929a31a972b244cbffe89 patch 8.2.2840: Vim9: member operation not fully tested Commit: https://github.com/vim/vim/commit/261417b872e6449fe1ca4e7d10f1cfd9736ea453 Author: Bram Moolenaar Date: Thu May 6 21:04:55 2021 +0200 patch 8.2.2840: Vim9: member operation not fully tested Problem: Vim9: member operation not fully tested. Solution: Add a few tests. diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -3066,6 +3066,10 @@ def Test_expr7_string_subscript() assert_equal('ábçd', text[: 3]) assert_equal('bçdëf', text[1 :]) assert_equal('ábçdëf', text[:]) + + assert_equal('a', g:astring[0]) + assert_equal('sd', g:astring[1 : 2]) + assert_equal('asdf', g:astring[:]) END CheckDefAndScriptSuccess(lines) @@ -3135,6 +3139,9 @@ def Test_expr7_list_subscript() assert_equal([0], list[0 : -5]) assert_equal([], list[0 : -6]) assert_equal([], list[0 : -99]) + + assert_equal(2, g:alist[0]) + assert_equal([2, 3, 4], g:alist[:]) END CheckDefAndScriptSuccess(lines) @@ -3157,6 +3164,9 @@ def Test_expr7_dict_subscript() var res = l[0].lnum > l[1].lnum assert_true(res) + assert_equal(2, g:adict['aaa']) + assert_equal(8, g:adict.bbb) + var dd = {} def Func1() eval dd.key1.key2 @@ -3169,6 +3179,18 @@ def Test_expr7_dict_subscript() CheckDefAndScriptSuccess(lines) enddef +def Test_expr7_blob_subscript() + var lines =<< trim END + var b = 0z112233 + assert_equal(0x11, b[0]) + assert_equal(0z112233, b[:]) + + assert_equal(0x01, g:ablob[0]) + assert_equal(0z01ab, g:ablob[:]) + END + CheckDefAndScriptSuccess(lines) +enddef + def Test_expr7_subscript_linebreak() var lines =<< trim END var range = range( diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2840, +/**/ 2839, /**/ 2838, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2708,41 +2708,40 @@ clear_ppconst(ppconst_T *ppconst) /* * Compile getting a member from a list/dict/string/blob. Stack has the - * indexable value and the index. + * indexable value and the index or the two indexes of a slice. */ static int compile_member(int is_slice, cctx_T *cctx) { type_T **typep; garray_T *stack = &cctx->ctx_type_stack; - vartype_T vtype; - type_T *valtype; - - // We can index a list and a dict. If we don't know the type - // we can use the index value type. - // TODO: If we don't know use an instruction to figure it out at - // runtime. + vartype_T vartype; + type_T *idxtype; + + // We can index a list, dict and blob. If we don't know the type + // we can use the index value type. If we still don't know use an "ANY" + // instruction. typep = ((type_T **)stack->ga_data) + stack->ga_len - (is_slice ? 3 : 2); - vtype = (*typep)->tt_type; - valtype = ((type_T **)stack->ga_data)[stack->ga_len - 1]; + vartype = (*typep)->tt_type; + idxtype = ((type_T **)stack->ga_data)[stack->ga_len - 1]; // If the index is a string, the variable must be a Dict. - if (*typep == &t_any && valtype == &t_string) - vtype = VAR_DICT; - if (vtype == VAR_STRING || vtype == VAR_LIST || vtype == VAR_BLOB) - { - if (need_type(valtype, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL) + if (*typep == &t_any && idxtype == &t_string) + vartype = VAR_DICT; + if (vartype == VAR_STRING || vartype == VAR_LIST || vartype == VAR_BLOB) + { + if (need_type(idxtype, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; if (is_slice) { - valtype = ((type_T **)stack->ga_data)[stack->ga_len - 2]; - if (need_type(valtype, &t_number, -2, 0, cctx, + idxtype = ((type_T **)stack->ga_data)[stack->ga_len - 2]; + if (need_type(idxtype, &t_number, -2, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; } } - if (vtype == VAR_DICT) + if (vartype == VAR_DICT) { if (is_slice) { @@ -2768,7 +2767,7 @@ compile_member(int is_slice, cctx_T *cct if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL) return FAIL; } - else if (vtype == VAR_STRING) + else if (vartype == VAR_STRING) { *typep = &t_string; if ((is_slice @@ -2776,7 +2775,7 @@ compile_member(int is_slice, cctx_T *cct : generate_instr_drop(cctx, ISN_STRINDEX, 1)) == FAIL) return FAIL; } - else if (vtype == VAR_BLOB) + else if (vartype == VAR_BLOB) { if (is_slice) { @@ -2791,12 +2790,12 @@ compile_member(int is_slice, cctx_T *cct return FAIL; } } - else if (vtype == VAR_LIST || *typep == &t_any) + else if (vartype == VAR_LIST || *typep == &t_any) { if (is_slice) { if (generate_instr_drop(cctx, - vtype == VAR_LIST ? ISN_LISTSLICE : ISN_ANYSLICE, + vartype == VAR_LIST ? ISN_LISTSLICE : ISN_ANYSLICE, 2) == FAIL) return FAIL; } @@ -2810,7 +2809,8 @@ compile_member(int is_slice, cctx_T *cct *typep = &t_any; } if (generate_instr_drop(cctx, - vtype == VAR_LIST ? ISN_LISTINDEX : ISN_ANYINDEX, 1) == FAIL) + vartype == VAR_LIST ? ISN_LISTINDEX : ISN_ANYINDEX, 1) + == FAIL) return FAIL; } }