Mercurial > vim
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) |