diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/globals.h | 202 | ||||
-rw-r--r-- | src/structs.h | 9 | ||||
-rw-r--r-- | src/testdir/test_vim9_func.vim | 16 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9execute.c | 23 | ||||
-rw-r--r-- | src/vim9type.c | 22 |
6 files changed, 158 insertions, 116 deletions
diff --git a/src/globals.h b/src/globals.h index e38b471657..3c401a290f 100644 --- a/src/globals.h +++ b/src/globals.h @@ -430,107 +430,111 @@ EXTERN int garbage_collect_at_exit INIT(= FALSE); #define t_number_bool (static_types[14]) #define t_const_number_bool (static_types[15]) -#define t_float (static_types[16]) -#define t_const_float (static_types[17]) +// t_number_float - number that can be used as a float +#define t_number_float (static_types[16]) +#define t_const_number_float (static_types[17]) -#define t_string (static_types[18]) -#define t_const_string (static_types[19]) +#define t_float (static_types[18]) +#define t_const_float (static_types[19]) -#define t_blob (static_types[20]) -#define t_const_blob (static_types[21]) +#define t_string (static_types[20]) +#define t_const_string (static_types[21]) -#define t_blob_null (static_types[22]) -#define t_const_blob_null (static_types[23]) +#define t_blob (static_types[22]) +#define t_const_blob (static_types[23]) -#define t_job (static_types[24]) -#define t_const_job (static_types[25]) +#define t_blob_null (static_types[24]) +#define t_const_blob_null (static_types[25]) -#define t_channel (static_types[26]) -#define t_const_channel (static_types[27]) +#define t_job (static_types[26]) +#define t_const_job (static_types[27]) + +#define t_channel (static_types[28]) +#define t_const_channel (static_types[29]) // t_number_or_string - Special value used for @#. -#define t_number_or_string (static_types[28]) -#define t_const_number_or_string (static_types[29]) +#define t_number_or_string (static_types[30]) +#define t_const_number_or_string (static_types[31]) // t_func_unknown - function with any arguments and no or unknown return value -#define t_func_unknown (static_types[30]) -#define t_const_func_unknown (static_types[31]) +#define t_func_unknown (static_types[32]) +#define t_const_func_unknown (static_types[33]) // t_func_void - function with any arguments and no return value -#define t_func_void (static_types[32]) -#define t_const_func_void (static_types[33]) +#define t_func_void (static_types[34]) +#define t_const_func_void (static_types[35]) -#define t_func_any (static_types[34]) -#define t_const_func_any (static_types[35]) +#define t_func_any (static_types[36]) +#define t_const_func_any (static_types[37]) -#define t_func_number (static_types[36]) -#define t_const_func_number (static_types[37]) +#define t_func_number (static_types[38]) +#define t_const_func_number (static_types[39]) -#define t_func_string (static_types[38]) -#define t_const_func_string (static_types[39]) +#define t_func_string (static_types[40]) +#define t_const_func_string (static_types[41]) -#define t_func_bool (static_types[40]) -#define t_const_func_bool (static_types[41]) +#define t_func_bool (static_types[42]) +#define t_const_func_bool (static_types[43]) // t_func_0_void - function without arguments and nor return value -#define t_func_0_void (static_types[42]) -#define t_const_func_0_void (static_types[43]) +#define t_func_0_void (static_types[44]) +#define t_const_func_0_void (static_types[45]) -#define t_func_0_any (static_types[44]) -#define t_const_func_0_any (static_types[45]) +#define t_func_0_any (static_types[46]) +#define t_const_func_0_any (static_types[47]) -#define t_func_0_number (static_types[46]) -#define t_const_func_0_number (static_types[47]) +#define t_func_0_number (static_types[48]) +#define t_const_func_0_number (static_types[49]) -#define t_func_0_string (static_types[48]) -#define t_const_func_0_string (static_types[49]) +#define t_func_0_string (static_types[50]) +#define t_const_func_0_string (static_types[51]) -#define t_list_any (static_types[50]) -#define t_const_list_any (static_types[51]) +#define t_list_any (static_types[52]) +#define t_const_list_any (static_types[53]) -#define t_dict_any (static_types[52]) -#define t_const_dict_any (static_types[53]) +#define t_dict_any (static_types[54]) +#define t_const_dict_any (static_types[55]) -#define t_list_empty (static_types[54]) -#define t_const_list_empty (static_types[55]) +#define t_list_empty (static_types[56]) +#define t_const_list_empty (static_types[57]) -#define t_dict_empty (static_types[56]) -#define t_const_dict_empty (static_types[57]) +#define t_dict_empty (static_types[58]) +#define t_const_dict_empty (static_types[59]) -#define t_list_bool (static_types[58]) -#define t_const_list_bool (static_types[59]) +#define t_list_bool (static_types[60]) +#define t_const_list_bool (static_types[61]) -#define t_list_number (static_types[60]) -#define t_const_list_number (static_types[61]) +#define t_list_number (static_types[62]) +#define t_const_list_number (static_types[63]) -#define t_list_string (static_types[62]) -#define t_const_list_string (static_types[63]) +#define t_list_string (static_types[64]) +#define t_const_list_string (static_types[65]) -#define t_list_job (static_types[64]) -#define t_const_list_job (static_types[65]) +#define t_list_job (static_types[66]) +#define t_const_list_job (static_types[67]) -#define t_list_dict_any (static_types[66]) -#define t_const_list_dict_any (static_types[67]) +#define t_list_dict_any (static_types[68]) +#define t_const_list_dict_any (static_types[69]) -#define t_list_list_any (static_types[68]) -#define t_const_list_list_any (static_types[69]) +#define t_list_list_any (static_types[70]) +#define t_const_list_list_any (static_types[71]) -#define t_list_list_string (static_types[70]) -#define t_const_list_list_string (static_types[71]) +#define t_list_list_string (static_types[72]) +#define t_const_list_list_string (static_types[73]) -#define t_dict_bool (static_types[72]) -#define t_const_dict_bool (static_types[73]) +#define t_dict_bool (static_types[74]) +#define t_const_dict_bool (static_types[75]) -#define t_dict_number (static_types[74]) -#define t_const_dict_number (static_types[75]) +#define t_dict_number (static_types[76]) +#define t_const_dict_number (static_types[77]) -#define t_dict_string (static_types[76]) -#define t_const_dict_string (static_types[77]) +#define t_dict_string (static_types[78]) +#define t_const_dict_string (static_types[79]) -#define t_super (static_types[78]) -#define t_const_super (static_types[79]) +#define t_super (static_types[80]) +#define t_const_super (static_types[81]) -EXTERN type_T static_types[80] +EXTERN type_T static_types[82] #ifdef DO_INIT = { // 0: t_unknown @@ -565,131 +569,135 @@ EXTERN type_T static_types[80] {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_BOOL_OK, NULL, NULL}, {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_BOOL_OK|TTFLAG_CONST, NULL, NULL}, - // 16: t_float + // 16: t_number_float + {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_FLOAT_OK, NULL, NULL}, + {VAR_NUMBER, 0, 0, TTFLAG_STATIC|TTFLAG_FLOAT_OK|TTFLAG_CONST, NULL, NULL}, + + // 18: t_float {VAR_FLOAT, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_FLOAT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, - // 18: t_string + // 20: t_string {VAR_STRING, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_STRING, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, - // 20: t_blob + // 22: t_blob {VAR_BLOB, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_BLOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, - // 22: t_blob_null + // 24: t_blob_null {VAR_BLOB, 0, 0, TTFLAG_STATIC, &t_void, NULL}, {VAR_BLOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL}, - // 24: t_job + // 26: t_job {VAR_JOB, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_JOB, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, - // 26: t_channel + // 28: t_channel {VAR_CHANNEL, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_CHANNEL, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, - // 28: t_number_or_string + // 30: t_number_or_string {VAR_STRING, 0, 0, TTFLAG_STATIC, NULL, NULL}, {VAR_STRING, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, NULL, NULL}, - // 30: t_func_unknown + // 32: t_func_unknown {VAR_FUNC, -1, -1, TTFLAG_STATIC, &t_unknown, NULL}, {VAR_FUNC, -1, -1, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL}, - // 32: t_func_void + // 34: t_func_void {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_void, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL}, - // 34: t_func_any + // 36: t_func_any {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_any, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL}, - // 36: t_func_number + // 38: t_func_number {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_number, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL}, - // 38: t_func_string + // 40: t_func_string {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_string, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL}, - // 40: t_func_bool + // 42: t_func_bool {VAR_FUNC, -1, 0, TTFLAG_STATIC, &t_bool, NULL}, {VAR_FUNC, -1, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL}, - // 42: t_func_0_void + // 44: t_func_0_void {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_void, NULL}, {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_void, NULL}, - // 44: t_func_0_any + // 46: t_func_0_any {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_any, NULL}, {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL}, - // 46: t_func_0_number + // 48: t_func_0_number {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_number, NULL}, {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL}, - // 48: t_func_0_string + // 50: t_func_0_string {VAR_FUNC, 0, 0, TTFLAG_STATIC, &t_string, NULL}, {VAR_FUNC, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL}, - // 50: t_list_any + // 52: t_list_any {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_any, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL}, - // 52: t_dict_any + // 54: t_dict_any {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_any, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_any, NULL}, - // 54: t_list_empty + // 56: t_list_empty {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_unknown, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL}, - // 56: t_dict_empty + // 58: t_dict_empty {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_unknown, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_unknown, NULL}, - // 58: t_list_bool + // 60: t_list_bool {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_bool, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL}, - // 60: t_list_number + // 62: t_list_number {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_number, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL}, - // 62: t_list_string + // 64: t_list_string {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_string, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL}, - // 64: t_list_job + // 66: t_list_job {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_job, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_job, NULL}, - // 66: t_list_dict_any + // 68: t_list_dict_any {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_dict_any, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_dict_any, NULL}, - // 68: t_list_list_any + // 70: t_list_list_any {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_any, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_any, NULL}, - // 70: t_list_list_string + // 72: t_list_list_string {VAR_LIST, 0, 0, TTFLAG_STATIC, &t_list_string, NULL}, {VAR_LIST, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_list_string, NULL}, - // 72: t_dict_bool + // 74: t_dict_bool {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_bool, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL}, - // 74: t_dict_number + // 76: t_dict_number {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_number, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_number, NULL}, - // 76: t_dict_string + // 78: t_dict_string {VAR_DICT, 0, 0, TTFLAG_STATIC, &t_string, NULL}, {VAR_DICT, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_string, NULL}, - // 78: t_super (VAR_CLASS with tt_member set to &t_bool + // 80: t_super (VAR_CLASS with tt_member set to &t_bool {VAR_CLASS, 0, 0, TTFLAG_STATIC, &t_bool, NULL}, {VAR_CLASS, 0, 0, TTFLAG_STATIC|TTFLAG_CONST, &t_bool, NULL}, } diff --git a/src/structs.h b/src/structs.h index a015dec49f..3b5a233f63 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1462,10 +1462,11 @@ typedef struct { #define TTFLAG_VARARGS 0x01 // func args ends with "..." #define TTFLAG_BOOL_OK 0x02 // can be converted to bool -#define TTFLAG_NUMBER_OK 0x04 // tt_type is VAR_FLOAT, VAR_NUMBER is OK -#define TTFLAG_STATIC 0x08 // one of the static types, e.g. t_any -#define TTFLAG_CONST 0x10 // cannot be changed -#define TTFLAG_SUPER 0x20 // object from "super". +#define TTFLAG_FLOAT_OK 0x04 // number can be used/converted to float +#define TTFLAG_NUMBER_OK 0x08 // number can be used for a float +#define TTFLAG_STATIC 0x10 // one of the static types, e.g. t_any +#define TTFLAG_CONST 0x20 // cannot be changed +#define TTFLAG_SUPER 0x40 // object from "super". typedef enum { ACCESS_PRIVATE, // read/write only inside th class diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index bf8b705ed5..44a8d4b106 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -727,6 +727,18 @@ def Test_call_default_args() v9.CheckScriptSuccess(lines) enddef +def Test_convert_number_to_float() + var lines =<< trim END + vim9script + def Foo(a: float, b: float): float + return a + b + enddef + + assert_equal(5.3, Foo(3.3, 2)) + END + v9.CheckScriptSuccess(lines) +enddef + def s:FuncWithComment( # comment a: number, #comment b: bool, # comment @@ -4311,10 +4323,10 @@ def Test_lambda_argument_type_check() return sum enddef - const ml = [3.0, 2, 7] + const ml = [3.0, 2, '7'] echo Scan(ml)->Sum() END - v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got number') + v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got string') enddef def Test_multiple_funcref() diff --git a/src/version.c b/src/version.c index f15061adc2..29c788d2b4 100644 --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1224, +/**/ 1223, /**/ 1222, diff --git a/src/vim9execute.c b/src/vim9execute.c index d0dbefc43b..57f875de35 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -5822,12 +5822,25 @@ call_def_function( } else { - if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len - && check_typval_arg_type( - ufunc->uf_arg_types[idx], tv, + int done = FALSE; + if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len) + { + type_T *expected = ufunc->uf_arg_types[idx]; + if (expected->tt_type == VAR_FLOAT && tv->v_type == VAR_NUMBER) + { + // When a float is expected and a number was given, convert + // the value. + STACK_TV_BOT(0)->v_type = VAR_FLOAT; + STACK_TV_BOT(0)->v_lock = 0; + STACK_TV_BOT(0)->vval.v_float = tv->vval.v_number; + done = TRUE; + } + else if (check_typval_arg_type(expected, tv, NULL, argv_idx + 1) == FAIL) - goto failed_early; - copy_tv(tv, STACK_TV_BOT(0)); + goto failed_early; + } + if (!done) + copy_tv(tv, STACK_TV_BOT(0)); } ++ectx.ec_stack.ga_len; } diff --git a/src/vim9type.c b/src/vim9type.c index 08dabd1c22..61853956e8 100644 --- a/src/vim9type.c +++ b/src/vim9type.c @@ -628,12 +628,17 @@ typval2type(typval_T *tv, int copyID, garray_T *type_gap, int flags) { type_T *type = typval2type_int(tv, copyID, type_gap, flags); - if (type != NULL && type != &t_bool - && (tv->v_type == VAR_NUMBER + if (type != NULL) + { + if (type != &t_bool && (tv->v_type == VAR_NUMBER && (tv->vval.v_number == 0 || tv->vval.v_number == 1))) - // Number 0 and 1 and expression with "&&" or "||" can also be used for - // bool. - type = &t_number_bool; + // Number 0 and 1 and expression with "&&" or "||" can also be used + // for bool. + type = &t_number_bool; + else if (type != &t_float && tv->v_type == VAR_NUMBER) + // A number can also be used for float. + type = &t_number_float; + } return type; } @@ -821,9 +826,10 @@ check_type_maybe( // Using number 0 or 1 for bool is OK. return OK; if (expected->tt_type == VAR_FLOAT - && (expected->tt_flags & TTFLAG_NUMBER_OK) - && actual->tt_type == VAR_NUMBER) - // Using number where float is expected is OK here. + && actual->tt_type == VAR_NUMBER + && ((expected->tt_flags & TTFLAG_NUMBER_OK) + || (actual->tt_flags & TTFLAG_FLOAT_OK))) + // Using a number where a float is expected is OK here. return OK; if (give_msg) type_mismatch_where(expected, actual, where); |