mirror of
https://github.com/vim/vim.git
synced 2025-07-25 10:54:51 -04:00
patch 8.2.1647: Vim9: result of expression with && and || is not a bool
Problem: Vim9: result of expression with && and || cannot be assigned to a bool variable. Solution: Add the TTFLAG_BOOL_OK flag and convert the value if needed.
This commit is contained in:
parent
33e3346322
commit
4ed124cc6c
@ -1199,6 +1199,29 @@ def Test_disassemble_invert_bool()
|
|||||||
assert_equal(true, InvertBool())
|
assert_equal(true, InvertBool())
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def ReturnBool(): bool
|
||||||
|
let var: bool = "no" && [] || 123
|
||||||
|
return var
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_disassemble_return_bool()
|
||||||
|
let instr = execute('disassemble ReturnBool')
|
||||||
|
assert_match('ReturnBool\_s*' ..
|
||||||
|
'let var: bool = "no" && \[\] || 123\_s*' ..
|
||||||
|
'0 PUSHS "no"\_s*' ..
|
||||||
|
'1 JUMP_AND_KEEP_IF_FALSE -> 3\_s*' ..
|
||||||
|
'2 NEWLIST size 0\_s*' ..
|
||||||
|
'3 JUMP_AND_KEEP_IF_TRUE -> 5\_s*' ..
|
||||||
|
'4 PUSHNR 123\_s*' ..
|
||||||
|
'5 2BOOL (!!val)\_s*' ..
|
||||||
|
'\d STORE $0\_s*' ..
|
||||||
|
'return var\_s*' ..
|
||||||
|
'\d LOAD $0\_s*' ..
|
||||||
|
'\d RETURN',
|
||||||
|
instr)
|
||||||
|
assert_equal(true, InvertBool())
|
||||||
|
enddef
|
||||||
|
|
||||||
def Test_disassemble_compare()
|
def Test_disassemble_compare()
|
||||||
let cases = [
|
let cases = [
|
||||||
['true == isFalse', 'COMPAREBOOL =='],
|
['true == isFalse', 'COMPAREBOOL =='],
|
||||||
|
@ -46,9 +46,16 @@ def Test_assignment_bool()
|
|||||||
assert_equal(v:false, bool2)
|
assert_equal(v:false, bool2)
|
||||||
|
|
||||||
let bool3: bool = 0
|
let bool3: bool = 0
|
||||||
assert_equal(0, bool3)
|
assert_equal(false, bool3)
|
||||||
let bool4: bool = 1
|
let bool4: bool = 1
|
||||||
assert_equal(1, bool4)
|
assert_equal(true, bool4)
|
||||||
|
|
||||||
|
let bool5: bool = 'yes' && 'no'
|
||||||
|
assert_equal(true, bool5)
|
||||||
|
let bool6: bool = [] && 99
|
||||||
|
assert_equal(false, bool6)
|
||||||
|
let bool7: bool = [] || #{a: 1} && 99
|
||||||
|
assert_equal(true, bool7)
|
||||||
|
|
||||||
let lines =<< trim END
|
let lines =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
@ -57,8 +64,15 @@ def Test_assignment_bool()
|
|||||||
return flag
|
return flag
|
||||||
enddef
|
enddef
|
||||||
let flag: bool = GetFlag()
|
let flag: bool = GetFlag()
|
||||||
|
assert_equal(true, flag)
|
||||||
flag = 0
|
flag = 0
|
||||||
|
# assert_equal(false, flag)
|
||||||
flag = 1
|
flag = 1
|
||||||
|
# assert_equal(true, flag)
|
||||||
|
# flag = 99 || 123
|
||||||
|
# assert_equal(true, flag)
|
||||||
|
# flag = 'yes' && []
|
||||||
|
# assert_equal(false, flag)
|
||||||
END
|
END
|
||||||
CheckScriptSuccess(lines)
|
CheckScriptSuccess(lines)
|
||||||
CheckDefAndScriptFailure(['let x: bool = 2'], 'E1012:')
|
CheckDefAndScriptFailure(['let x: bool = 2'], 'E1012:')
|
||||||
|
@ -750,6 +750,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 */
|
||||||
|
/**/
|
||||||
|
1647,
|
||||||
/**/
|
/**/
|
||||||
1646,
|
1646,
|
||||||
/**/
|
/**/
|
||||||
|
@ -729,6 +729,15 @@ need_type(
|
|||||||
cctx_T *cctx,
|
cctx_T *cctx,
|
||||||
int silent)
|
int silent)
|
||||||
{
|
{
|
||||||
|
if (expected == &t_bool && actual != &t_bool
|
||||||
|
&& (actual->tt_flags & TTFLAG_BOOL_OK))
|
||||||
|
{
|
||||||
|
// Using "0", "1" or the result of an expression with "&&" or "||" as a
|
||||||
|
// boolean is OK but requires a conversion.
|
||||||
|
generate_2BOOL(cctx, FALSE);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (check_type(expected, actual, FALSE, 0) == OK)
|
if (check_type(expected, actual, FALSE, 0) == OK)
|
||||||
return OK;
|
return OK;
|
||||||
if (actual->tt_type != VAR_ANY
|
if (actual->tt_type != VAR_ANY
|
||||||
@ -3926,6 +3935,8 @@ compile_and_or(
|
|||||||
{
|
{
|
||||||
garray_T *instr = &cctx->ctx_instr;
|
garray_T *instr = &cctx->ctx_instr;
|
||||||
garray_T end_ga;
|
garray_T end_ga;
|
||||||
|
garray_T *stack = &cctx->ctx_type_stack;
|
||||||
|
type_T **typep;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Repeat until there is no following "||" or "&&"
|
* Repeat until there is no following "||" or "&&"
|
||||||
@ -3985,6 +3996,20 @@ compile_and_or(
|
|||||||
isn->isn_arg.jump.jump_where = instr->ga_len;
|
isn->isn_arg.jump.jump_where = instr->ga_len;
|
||||||
}
|
}
|
||||||
ga_clear(&end_ga);
|
ga_clear(&end_ga);
|
||||||
|
|
||||||
|
// The resulting type can be used as a bool.
|
||||||
|
typep = ((type_T **)stack->ga_data) + stack->ga_len - 1;
|
||||||
|
if (*typep != &t_bool)
|
||||||
|
{
|
||||||
|
type_T *type = alloc_type(cctx->ctx_type_list);
|
||||||
|
|
||||||
|
if (type != NULL)
|
||||||
|
{
|
||||||
|
*type = **typep;
|
||||||
|
type->tt_flags |= TTFLAG_BOOL_OK;
|
||||||
|
*typep = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user