comparison src/evalfunc.c @ 23640:8dcb2255ff9a v8.2.2362

patch 8.2.2362: Vim9: check of builtin function argument type is incomplete Commit: https://github.com/vim/vim/commit/351ead09dd365ebdee2bfa27ab22542d4920c779 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jan 16 16:07:01 2021 +0100 patch 8.2.2362: Vim9: check of builtin function argument type is incomplete Problem: Vim9: check of builtin function argument type is incomplete. Solution: Use need_type() instead of check_arg_type().
author Bram Moolenaar <Bram@vim.org>
date Sat, 16 Jan 2021 16:15:04 +0100
parents 1816ea68c022
children 8df4e9e2394f
comparison
equal deleted inserted replaced
23639:a93ecfa78aef 23640:8dcb2255ff9a
273 // Context passed to an arg_ function. 273 // Context passed to an arg_ function.
274 typedef struct { 274 typedef struct {
275 int arg_count; // actual argument count 275 int arg_count; // actual argument count
276 type_T **arg_types; // list of argument types 276 type_T **arg_types; // list of argument types
277 int arg_idx; // current argument index (first arg is zero) 277 int arg_idx; // current argument index (first arg is zero)
278 cctx_T *arg_cctx;
278 } argcontext_T; 279 } argcontext_T;
279 280
280 // A function to check one argument type. The first argument is the type to 281 // A function to check one argument type. The first argument is the type to
281 // check. If needed, other argument types can be obtained with the context. 282 // check. If needed, other argument types can be obtained with the context.
282 // E.g. if "arg_idx" is 1, then (type - 1) is the first argument type. 283 // E.g. if "arg_idx" is 1, then (type - 1) is the first argument type.
283 typedef int (*argcheck_T)(type_T *, argcontext_T *); 284 typedef int (*argcheck_T)(type_T *, argcontext_T *);
285
286 /*
287 * Call need_type() to check an argument type.
288 */
289 static int
290 check_arg_type(
291 type_T *expected,
292 type_T *actual,
293 argcontext_T *context)
294 {
295 // TODO: would be useful to know if "actual" is a constant and pass it to
296 // need_type() to get a compile time error if possible.
297 return need_type(actual, expected,
298 context->arg_idx - context->arg_count, context->arg_idx + 1,
299 context->arg_cctx, FALSE, FALSE);
300 }
284 301
285 /* 302 /*
286 * Check "type" is a float or a number. 303 * Check "type" is a float or a number.
287 */ 304 */
288 static int 305 static int
299 * Check "type" is a number. 316 * Check "type" is a number.
300 */ 317 */
301 static int 318 static int
302 arg_number(type_T *type, argcontext_T *context) 319 arg_number(type_T *type, argcontext_T *context)
303 { 320 {
304 return check_arg_type(&t_number, type, context->arg_idx + 1); 321 return check_arg_type(&t_number, type, context);
305 } 322 }
306 323
307 /* 324 /*
308 * Check "type" is a string. 325 * Check "type" is a string.
309 */ 326 */
310 static int 327 static int
311 arg_string(type_T *type, argcontext_T *context) 328 arg_string(type_T *type, argcontext_T *context)
312 { 329 {
313 return check_arg_type(&t_string, type, context->arg_idx + 1); 330 return check_arg_type(&t_string, type, context);
314 } 331 }
315 332
316 /* 333 /*
317 * Check "type" is a list or a blob. 334 * Check "type" is a list or a blob.
318 */ 335 */
346 static int 363 static int
347 arg_same_as_prev(type_T *type, argcontext_T *context) 364 arg_same_as_prev(type_T *type, argcontext_T *context)
348 { 365 {
349 type_T *prev_type = context->arg_types[context->arg_idx - 1]; 366 type_T *prev_type = context->arg_types[context->arg_idx - 1];
350 367
351 return check_arg_type(prev_type, type, context->arg_idx + 1); 368 return check_arg_type(prev_type, type, context);
352 } 369 }
353 370
354 /* 371 /*
355 * Check "type" is the same basic type as the previous argument, checks list or 372 * Check "type" is the same basic type as the previous argument, checks list or
356 * dict vs other type, but not member type. 373 * dict vs other type, but not member type.
360 arg_same_struct_as_prev(type_T *type, argcontext_T *context) 377 arg_same_struct_as_prev(type_T *type, argcontext_T *context)
361 { 378 {
362 type_T *prev_type = context->arg_types[context->arg_idx - 1]; 379 type_T *prev_type = context->arg_types[context->arg_idx - 1];
363 380
364 if (prev_type->tt_type != context->arg_types[context->arg_idx]->tt_type) 381 if (prev_type->tt_type != context->arg_types[context->arg_idx]->tt_type)
365 return check_arg_type(prev_type, type, context->arg_idx + 1); 382 return check_arg_type(prev_type, type, context);
366 return OK; 383 return OK;
367 } 384 }
368 385
369 /* 386 /*
370 * Check "type" is an item of the list or blob of the previous arg. 387 * Check "type" is an item of the list or blob of the previous arg.
382 expected = &t_number; 399 expected = &t_number;
383 else 400 else
384 // probably VAR_ANY, can't check 401 // probably VAR_ANY, can't check
385 return OK; 402 return OK;
386 403
387 return check_arg_type(expected, type, context->arg_idx + 1); 404 return check_arg_type(expected, type, context);
388 } 405 }
389 406
390 /* 407 /*
391 * Check "type" which is the third argument of extend(). 408 * Check "type" which is the third argument of extend().
392 */ 409 */
1929 * Check the argument types for builting function "idx". 1946 * Check the argument types for builting function "idx".
1930 * Uses the list of types on the type stack: "types". 1947 * Uses the list of types on the type stack: "types".
1931 * Return FAIL and gives an error message when a type is wrong. 1948 * Return FAIL and gives an error message when a type is wrong.
1932 */ 1949 */
1933 int 1950 int
1934 internal_func_check_arg_types(type_T **types, int idx, int argcount) 1951 internal_func_check_arg_types(
1952 type_T **types,
1953 int idx,
1954 int argcount,
1955 cctx_T *cctx)
1935 { 1956 {
1936 argcheck_T *argchecks = global_functions[idx].f_argcheck; 1957 argcheck_T *argchecks = global_functions[idx].f_argcheck;
1937 int i; 1958 int i;
1938 1959
1939 if (argchecks != NULL) 1960 if (argchecks != NULL)
1940 { 1961 {
1941 argcontext_T context; 1962 argcontext_T context;
1942 1963
1943 context.arg_count = argcount; 1964 context.arg_count = argcount;
1944 context.arg_types = types; 1965 context.arg_types = types;
1966 context.arg_cctx = cctx;
1945 for (i = 0; i < argcount; ++i) 1967 for (i = 0; i < argcount; ++i)
1946 if (argchecks[i] != NULL) 1968 if (argchecks[i] != NULL)
1947 { 1969 {
1948 context.arg_idx = i; 1970 context.arg_idx = i;
1949 if (argchecks[i](types[i], &context) == FAIL) 1971 if (argchecks[i](types[i], &context) == FAIL)