1
0
forked from aniani/vim

patch 8.2.1650: Vim9: result of && and || expression is not bool in script

Problem:    Vim9: result of && and || expression cannot be assigned to a bool
            at the script level.
Solution:   Add the VAR_BOOL_OK flag.  Convert to bool when needed.
This commit is contained in:
Bram Moolenaar
2020-09-09 22:27:58 +02:00
parent 3e4cc9671c
commit c1ec0422e4
8 changed files with 92 additions and 29 deletions

View File

@@ -199,28 +199,16 @@ func_type_add_arg_types(
* Get a type_T for a typval_T.
* "type_list" is used to temporarily create types in.
*/
type_T *
typval2type(typval_T *tv, garray_T *type_gap)
static type_T *
typval2type_int(typval_T *tv, garray_T *type_gap)
{
type_T *type;
type_T *member_type;
if (tv->v_type == VAR_NUMBER)
{
if (tv->vval.v_number == 0 || tv->vval.v_number == 1)
{
// number 0 and 1 can also be used for bool
type = alloc_type(type_gap);
if (type == NULL)
return NULL;
type->tt_type = VAR_NUMBER;
type->tt_flags = TTFLAG_BOOL_OK;
return type;
}
return &t_number;
}
if (tv->v_type == VAR_BOOL)
return &t_bool; // not used
return &t_bool;
if (tv->v_type == VAR_STRING)
return &t_string;
@@ -297,6 +285,46 @@ typval2type(typval_T *tv, garray_T *type_gap)
return type;
}
/*
* Return TRUE if "tv" is not a bool but should be converted to bool.
*/
int
need_convert_to_bool(type_T *type, typval_T *tv)
{
return type != NULL && type == &t_bool && tv->v_type != VAR_BOOL
&& ((tv->v_lock & VAR_BOOL_OK)
|| (tv->v_type == VAR_NUMBER
&& (tv->vval.v_number == 0 || tv->vval.v_number == 1)));
}
/*
* Get a type_T for a typval_T and handle VAR_BOOL_OK.
* "type_list" is used to temporarily create types in.
*/
type_T *
typval2type(typval_T *tv, garray_T *type_gap)
{
type_T *type = typval2type_int(tv, type_gap);
if (type != NULL && type != &t_bool
&& ((tv->v_type == VAR_NUMBER
&& (tv->vval.v_number == 0 || tv->vval.v_number == 1))
|| (tv->v_lock & VAR_BOOL_OK)))
{
type_T *newtype = alloc_type(type_gap);
// Number 0 and 1 and expression with "&&" or "||" can also be used
// for bool.
if (newtype != NULL)
{
*newtype = *type;
newtype->tt_flags = TTFLAG_BOOL_OK;
type = newtype;
}
}
return type;
}
/*
* Get a type_T for a typval_T, used for v: variables.
* "type_list" is used to temporarily create types in.
@@ -371,7 +399,7 @@ check_type(type_T *expected, type_T *actual, int give_msg, int argidx)
{
if (expected->tt_type != actual->tt_type)
{
if (expected->tt_type == VAR_BOOL && actual->tt_type == VAR_NUMBER
if (expected->tt_type == VAR_BOOL
&& (actual->tt_flags & TTFLAG_BOOL_OK))
// Using number 0 or 1 for bool is OK.
return OK;