summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-09-09 23:01:14 +0200
committerBram Moolenaar <Bram@vim.org>2021-09-09 23:01:14 +0200
commit07802044b90b2cbcc64b2dfe235f019d7c37589c (patch)
tree8f1d19d7f0204ad5876d73e83be81314e15350c7
parentefc084e3353d6854b6dac8b240f70cb0abb838ad (diff)
patch 8.2.3423: Vim9: list += list creates a new list in :def functionv8.2.3423
Problem: Vim9: list += list creates a new list in :def function. Solution: Append to the existing list.
-rw-r--r--src/structs.h3
-rw-r--r--src/testdir/test_vim9_assign.vim15
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c19
-rw-r--r--src/vim9execute.c9
5 files changed, 36 insertions, 12 deletions
diff --git a/src/structs.h b/src/structs.h
index 5d1496f590..8a94fc1155 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -4106,6 +4106,9 @@ typedef enum
EXPR_MULT, // *
EXPR_DIV, // /
EXPR_REM, // %
+ // used with ISN_ADDLIST
+ EXPR_COPY, // create new list
+ EXPR_APPEND, // append to first list
} exprtype_T;
/*
diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim
index 6b6311a56a..0d07e07eb7 100644
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -557,20 +557,21 @@ enddef
def Test_extend_list()
var lines =<< trim END
- vim9script
- var l: list<number>
- l += [123]
- assert_equal([123], l)
+ var l1: list<number>
+ var l2 = l1
+ assert_true(l1 is l2)
+ l1 += [123]
+ assert_equal([123], l1)
+ assert_true(l1 is l2)
END
- CheckScriptSuccess(lines)
+ CheckDefAndScriptSuccess(lines)
lines =<< trim END
- vim9script
var list: list<string>
extend(list, ['x'])
assert_equal(['x'], list)
END
- CheckScriptSuccess(lines)
+ CheckDefAndScriptSuccess(lines)
# appending to NULL list from a function
lines =<< trim END
diff --git a/src/version.c b/src/version.c
index 8cd295c1bb..9f4ea76131 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3423,
+/**/
3422,
/**/
3421,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index a4d8423fca..e7c7c07a69 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -690,12 +690,16 @@ check_number_or_float(vartype_T type1, vartype_T type2, char_u *op)
return OK;
}
+/*
+ * Generate instruction for "+". For a list this creates a new list.
+ */
static int
generate_add_instr(
cctx_T *cctx,
vartype_T vartype,
type_T *type1,
- type_T *type2)
+ type_T *type2,
+ exprtype_T expr_type)
{
garray_T *stack = &cctx->ctx_type_stack;
isn_T *isn = generate_instr_drop(cctx,
@@ -715,7 +719,12 @@ generate_add_instr(
return FAIL;
if (isn != NULL)
- isn->isn_arg.op.op_type = EXPR_ADD;
+ {
+ if (isn->isn_type == ISN_ADDLIST)
+ isn->isn_arg.op.op_type = expr_type;
+ else
+ isn->isn_arg.op.op_type = EXPR_ADD;
+ }
// When concatenating two lists with different member types the member type
// becomes "any".
@@ -769,7 +778,8 @@ generate_two_op(cctx_T *cctx, char_u *op)
switch (*op)
{
case '+':
- if (generate_add_instr(cctx, vartype, type1, type2) == FAIL)
+ if (generate_add_instr(cctx, vartype, type1, type2,
+ EXPR_COPY) == FAIL)
return FAIL;
break;
@@ -7186,7 +7196,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
{
if (generate_add_instr(cctx,
operator_type(lhs.lhs_member_type, stacktype),
- lhs.lhs_member_type, stacktype) == FAIL)
+ lhs.lhs_member_type, stacktype,
+ EXPR_APPEND) == FAIL)
goto theend;
}
else if (generate_two_op(cctx, op) == FAIL)
diff --git a/src/vim9execute.c b/src/vim9execute.c
index fdca977145..9fc942d379 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -3677,7 +3677,14 @@ exec_instructions(ectx_T *ectx)
// add two lists or blobs
if (iptr->isn_type == ISN_ADDLIST)
- eval_addlist(tv1, tv2);
+ {
+ if (iptr->isn_arg.op.op_type == EXPR_APPEND
+ && tv1->vval.v_list != NULL)
+ list_extend(tv1->vval.v_list, tv2->vval.v_list,
+ NULL);
+ else
+ eval_addlist(tv1, tv2);
+ }
else
eval_addblob(tv1, tv2);
clear_tv(tv2);