forked from aniani/vim
patch 8.2.3423: Vim9: list += list creates a new list in :def function
Problem: Vim9: list += list creates a new list in :def function. Solution: Append to the existing list.
This commit is contained in:
@@ -4106,6 +4106,9 @@ typedef enum
|
|||||||
EXPR_MULT, // *
|
EXPR_MULT, // *
|
||||||
EXPR_DIV, // /
|
EXPR_DIV, // /
|
||||||
EXPR_REM, // %
|
EXPR_REM, // %
|
||||||
|
// used with ISN_ADDLIST
|
||||||
|
EXPR_COPY, // create new list
|
||||||
|
EXPR_APPEND, // append to first list
|
||||||
} exprtype_T;
|
} exprtype_T;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -557,20 +557,21 @@ enddef
|
|||||||
|
|
||||||
def Test_extend_list()
|
def Test_extend_list()
|
||||||
var lines =<< trim END
|
var lines =<< trim END
|
||||||
vim9script
|
var l1: list<number>
|
||||||
var l: list<number>
|
var l2 = l1
|
||||||
l += [123]
|
assert_true(l1 is l2)
|
||||||
assert_equal([123], l)
|
l1 += [123]
|
||||||
|
assert_equal([123], l1)
|
||||||
|
assert_true(l1 is l2)
|
||||||
END
|
END
|
||||||
CheckScriptSuccess(lines)
|
CheckDefAndScriptSuccess(lines)
|
||||||
|
|
||||||
lines =<< trim END
|
lines =<< trim END
|
||||||
vim9script
|
|
||||||
var list: list<string>
|
var list: list<string>
|
||||||
extend(list, ['x'])
|
extend(list, ['x'])
|
||||||
assert_equal(['x'], list)
|
assert_equal(['x'], list)
|
||||||
END
|
END
|
||||||
CheckScriptSuccess(lines)
|
CheckDefAndScriptSuccess(lines)
|
||||||
|
|
||||||
# appending to NULL list from a function
|
# appending to NULL list from a function
|
||||||
lines =<< trim END
|
lines =<< trim END
|
||||||
|
@@ -755,6 +755,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
3423,
|
||||||
/**/
|
/**/
|
||||||
3422,
|
3422,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -690,12 +690,16 @@ check_number_or_float(vartype_T type1, vartype_T type2, char_u *op)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate instruction for "+". For a list this creates a new list.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
generate_add_instr(
|
generate_add_instr(
|
||||||
cctx_T *cctx,
|
cctx_T *cctx,
|
||||||
vartype_T vartype,
|
vartype_T vartype,
|
||||||
type_T *type1,
|
type_T *type1,
|
||||||
type_T *type2)
|
type_T *type2,
|
||||||
|
exprtype_T expr_type)
|
||||||
{
|
{
|
||||||
garray_T *stack = &cctx->ctx_type_stack;
|
garray_T *stack = &cctx->ctx_type_stack;
|
||||||
isn_T *isn = generate_instr_drop(cctx,
|
isn_T *isn = generate_instr_drop(cctx,
|
||||||
@@ -715,7 +719,12 @@ generate_add_instr(
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
if (isn != NULL)
|
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
|
// When concatenating two lists with different member types the member type
|
||||||
// becomes "any".
|
// becomes "any".
|
||||||
@@ -769,7 +778,8 @@ generate_two_op(cctx_T *cctx, char_u *op)
|
|||||||
switch (*op)
|
switch (*op)
|
||||||
{
|
{
|
||||||
case '+':
|
case '+':
|
||||||
if (generate_add_instr(cctx, vartype, type1, type2) == FAIL)
|
if (generate_add_instr(cctx, vartype, type1, type2,
|
||||||
|
EXPR_COPY) == FAIL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -7186,7 +7196,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
{
|
{
|
||||||
if (generate_add_instr(cctx,
|
if (generate_add_instr(cctx,
|
||||||
operator_type(lhs.lhs_member_type, stacktype),
|
operator_type(lhs.lhs_member_type, stacktype),
|
||||||
lhs.lhs_member_type, stacktype) == FAIL)
|
lhs.lhs_member_type, stacktype,
|
||||||
|
EXPR_APPEND) == FAIL)
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
else if (generate_two_op(cctx, op) == FAIL)
|
else if (generate_two_op(cctx, op) == FAIL)
|
||||||
|
@@ -3677,7 +3677,14 @@ exec_instructions(ectx_T *ectx)
|
|||||||
|
|
||||||
// add two lists or blobs
|
// add two lists or blobs
|
||||||
if (iptr->isn_type == ISN_ADDLIST)
|
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
|
else
|
||||||
eval_addblob(tv1, tv2);
|
eval_addblob(tv1, tv2);
|
||||||
clear_tv(tv2);
|
clear_tv(tv2);
|
||||||
|
Reference in New Issue
Block a user