summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-05-06 21:04:55 +0200
committerBram Moolenaar <Bram@vim.org>2021-05-06 21:04:55 +0200
commit261417b872e6449fe1ca4e7d10f1cfd9736ea453 (patch)
tree97f68dc8c3dca0d87049125471f26c6d51040c91
parent56318369750066718b880afa69e7ae3843d0410b (diff)
downloadvim-git-261417b872e6449fe1ca4e7d10f1cfd9736ea453.tar.gz
patch 8.2.2840: Vim9: member operation not fully testedv8.2.2840
Problem: Vim9: member operation not fully tested. Solution: Add a few tests.
-rw-r--r--src/testdir/test_vim9_expr.vim22
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c42
3 files changed, 45 insertions, 21 deletions
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index de77b198b..718db8b70 100644
--- 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
index 36422c1d4..d2ffe6ff9 100644
--- 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
index a724d1ad9..f89b0d7d3 100644
--- 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;
+ vartype_T vartype;
+ type_T *idxtype;
- // 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.
+ // 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 (*typep == &t_any && idxtype == &t_string)
+ vartype = VAR_DICT;
+ if (vartype == VAR_STRING || vartype == VAR_LIST || vartype == VAR_BLOB)
{
- if (need_type(valtype, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL)
+ 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 *cctx)
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 *cctx)
: 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 *cctx)
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 *cctx)
*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;
}
}