* Note that "argtypes" is NULL if "argcount" is zero.
*/
static type_T *
-ret_void(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_void(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_void;
}
static type_T *
-ret_any(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_any(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_any;
}
static type_T *
-ret_bool(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_bool(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_bool;
}
static type_T *
-ret_number_bool(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_number_bool(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_number_bool;
}
static type_T *
-ret_number(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_number(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_number;
}
static type_T *
-ret_float(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_float(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_float;
}
static type_T *
-ret_string(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_string(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_string;
}
static type_T *
-ret_list_any(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_list_any(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_list_any;
}
static type_T *
-ret_list_number(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_list_number(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_list_number;
}
static type_T *
-ret_list_string(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_range(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type)
+{
+ // returning a list<number>, but it's not declared as such
+ *decl_type = &t_list_any;
+ return &t_list_number;
+}
+ static type_T *
+ret_list_string(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_list_string;
}
static type_T *
-ret_list_dict_any(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_list_dict_any(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_list_dict_any;
}
static type_T *
-ret_list_items(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_list_items(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_list_list_any;
}
static type_T *
-ret_list_string_items(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_list_string_items(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_list_list_string;
}
static type_T *
-ret_dict_any(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_dict_any(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_dict_any;
}
static type_T *
-ret_job_info(int argcount, type2_T *argtypes UNUSED)
+ret_job_info(int argcount,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
if (argcount == 0)
return &t_list_job;
return &t_dict_any;
}
static type_T *
-ret_dict_number(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_dict_number(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_dict_number;
}
static type_T *
-ret_dict_string(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_dict_string(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_dict_string;
}
static type_T *
-ret_blob(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_blob(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_blob;
}
static type_T *
-ret_func_any(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_func_any(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_func_any;
}
static type_T *
-ret_func_unknown(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_func_unknown(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_func_unknown;
}
static type_T *
-ret_channel(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_channel(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_channel;
}
static type_T *
-ret_job(int argcount UNUSED, type2_T *argtypes UNUSED)
+ret_job(int argcount UNUSED,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return &t_job;
}
static type_T *
-ret_first_arg(int argcount, type2_T *argtypes)
+ret_first_arg(int argcount,
+ type2_T *argtypes,
+ type_T **decl_type)
{
if (argcount > 0)
+ {
+ *decl_type = argtypes[0].type_decl;
return argtypes[0].type_curr;
+ }
return &t_void;
}
static type_T *
-ret_repeat(int argcount, type2_T *argtypes)
+ret_extend(int argcount,
+ type2_T *argtypes,
+ type_T **decl_type)
+{
+ if (argcount > 0)
+ {
+ *decl_type = argtypes[0].type_decl;
+ // if the second argument has a different current type then the current
+ // type is "any"
+ if (argcount > 1 && !equal_type(argtypes[0].type_curr,
+ argtypes[1].type_curr, 0))
+ {
+ if (argtypes[0].type_curr->tt_type == VAR_LIST)
+ return &t_list_any;
+ if (argtypes[0].type_curr->tt_type == VAR_DICT)
+ return &t_dict_any;
+ }
+ return argtypes[0].type_curr;
+ }
+ return &t_void;
+}
+ static type_T *
+ret_repeat(int argcount,
+ type2_T *argtypes,
+ type_T **decl_type UNUSED)
{
if (argcount == 0)
return &t_any;
}
// for map(): returns first argument but item type may differ
static type_T *
-ret_first_cont(int argcount, type2_T *argtypes)
+ret_first_cont(int argcount,
+ type2_T *argtypes,
+ type_T **decl_type UNUSED)
{
if (argcount > 0)
{
}
// for getline()
static type_T *
-ret_getline(int argcount, type2_T *argtypes UNUSED)
+ret_getline(int argcount,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
return argcount == 1 ? &t_string : &t_list_string;
}
// for finddir()
static type_T *
-ret_finddir(int argcount, type2_T *argtypes UNUSED)
+ret_finddir(int argcount,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
if (argcount < 3)
return &t_string;
* one.
*/
static type_T *
-ret_list_or_dict_0(int argcount, type2_T *argtypes UNUSED)
+ret_list_or_dict_0(int argcount,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
if (argcount > 0)
return &t_dict_any;
* are two.
*/
static type_T *
-ret_list_or_dict_1(int argcount, type2_T *argtypes UNUSED)
+ret_list_or_dict_1(int argcount,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
if (argcount > 1)
return &t_dict_any;
}
static type_T *
-ret_argv(int argcount, type2_T *argtypes UNUSED)
+ret_argv(int argcount,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
// argv() returns list of strings
if (argcount == 0)
}
static type_T *
-ret_remove(int argcount, type2_T *argtypes)
+ret_remove(int argcount,
+ type2_T *argtypes,
+ type_T **decl_type UNUSED)
{
if (argcount > 0)
{
if (argtypes[0].type_curr->tt_type == VAR_LIST
|| argtypes[0].type_curr->tt_type == VAR_DICT)
+ {
+ if (argtypes[0].type_curr->tt_type
+ == argtypes[0].type_decl->tt_type)
+ *decl_type = argtypes[0].type_decl->tt_member;
return argtypes[0].type_curr->tt_member;
+ }
if (argtypes[0].type_curr->tt_type == VAR_BLOB)
return &t_number;
}
}
static type_T *
-ret_getreg(int argcount, type2_T *argtypes UNUSED)
+ret_getreg(int argcount,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
// Assume that if the third argument is passed it's non-zero
if (argcount == 3)
}
static type_T *
-ret_maparg(int argcount, type2_T *argtypes UNUSED)
+ret_maparg(int argcount,
+ type2_T *argtypes UNUSED,
+ type_T **decl_type UNUSED)
{
// Assume that if the fourth argument is passed it's non-zero
if (argcount == 4)
char f_max_argc; // maximal number of arguments
char f_argtype; // for method: FEARG_ values
argcheck_T *f_argcheck; // list of functions to check argument types
- type_T *(*f_retfunc)(int argcount, type2_T *argtypes);
+ type_T *(*f_retfunc)(int argcount, type2_T *argtypes,
+ type_T **decl_type);
// return type function
void (*f_func)(typval_T *args, typval_T *rvar);
// implementation of function
{"expandcmd", 1, 1, FEARG_1, arg1_string,
ret_string, f_expandcmd},
{"extend", 2, 3, FEARG_1, arg23_extend,
- ret_first_arg, f_extend},
+ ret_extend, f_extend},
{"extendnew", 2, 3, FEARG_1, arg23_extendnew,
ret_first_cont, f_extendnew},
{"feedkeys", 1, 2, FEARG_1, arg2_string,
{"rand", 0, 1, FEARG_1, arg1_list_number,
ret_number, f_rand},
{"range", 1, 3, FEARG_1, arg3_number,
- ret_list_number, f_range},
+ ret_range, f_range},
{"readblob", 1, 1, FEARG_1, arg1_string,
ret_blob, f_readblob},
{"readdir", 1, 3, FEARG_1, arg3_string_any_dict,
/*
* Call the "f_retfunc" function to obtain the return type of function "idx".
+ * "decl_type" is set to the declared type.
* "argtypes" is the list of argument types or NULL when there are no
* arguments.
* "argcount" may be less than the actual count when only getting the type.
*/
type_T *
-internal_func_ret_type(int idx, int argcount, type2_T *argtypes)
+internal_func_ret_type(
+ int idx,
+ int argcount,
+ type2_T *argtypes,
+ type_T **decl_type)
{
- return global_functions[idx].f_retfunc(argcount, argtypes);
+ type_T *ret;
+
+ *decl_type = NULL;
+ ret = global_functions[idx].f_retfunc(argcount, argtypes, decl_type);
+ if (*decl_type == NULL)
+ *decl_type = ret;
+ return ret;
}
/*