comparison src/evalfunc.c @ 26935:ccb9be1cdd71 v8.2.3996

patch 8.2.3996: Vim9: type checking lacks information about declared type Commit: https://github.com/vim/vim/commit/078a46161e8b1b30bf306d6c1f4f0af7c616a989 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jan 4 15:17:03 2022 +0000 patch 8.2.3996: Vim9: type checking lacks information about declared type Problem: Vim9: type checking for list and dict lacks information about declared type. Solution: Add dv_decl_type and lv_decl_type. Refactor the type stack to store two types in each entry.
author Bram Moolenaar <Bram@vim.org>
date Tue, 04 Jan 2022 16:30:06 +0100
parents 46e6ef4cf18b
children e682a58399c1
comparison
equal deleted inserted replaced
26934:2d3dd8065e25 26935:ccb9be1cdd71
193 */ 193 */
194 194
195 // Context passed to an arg_ function. 195 // Context passed to an arg_ function.
196 typedef struct { 196 typedef struct {
197 int arg_count; // actual argument count 197 int arg_count; // actual argument count
198 type_T **arg_types; // list of argument types 198 type2_T *arg_types; // list of argument types
199 int arg_idx; // current argument index (first arg is zero) 199 int arg_idx; // current argument index (first arg is zero)
200 cctx_T *arg_cctx; 200 cctx_T *arg_cctx;
201 } argcontext_T; 201 } argcontext_T;
202 202
203 // A function to check one argument type. The first argument is the type to 203 // A function to check one argument type. The first argument is the type to
204 // check. If needed, other argument types can be obtained with the context. 204 // check. If needed, other argument types can be obtained with the context.
205 // E.g. if "arg_idx" is 1, then (type - 1) is the first argument type. 205 // E.g. if "arg_idx" is 1, then (type - 1) is the first argument type.
206 typedef int (*argcheck_T)(type_T *, argcontext_T *); 206 typedef int (*argcheck_T)(type_T *, type_T *, argcontext_T *);
207 207
208 /* 208 /*
209 * Call need_type() to check an argument type. 209 * Call need_type() to check an argument type.
210 */ 210 */
211 static int 211 static int
223 223
224 /* 224 /*
225 * Check "type" is a float or a number. 225 * Check "type" is a float or a number.
226 */ 226 */
227 static int 227 static int
228 arg_float_or_nr(type_T *type, argcontext_T *context) 228 arg_float_or_nr(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
229 { 229 {
230 if (type->tt_type == VAR_ANY 230 if (type->tt_type == VAR_ANY
231 || type->tt_type == VAR_UNKNOWN 231 || type->tt_type == VAR_UNKNOWN
232 || type->tt_type == VAR_FLOAT 232 || type->tt_type == VAR_FLOAT
233 || type->tt_type == VAR_NUMBER) 233 || type->tt_type == VAR_NUMBER)
238 238
239 /* 239 /*
240 * Check "type" is a number. 240 * Check "type" is a number.
241 */ 241 */
242 static int 242 static int
243 arg_number(type_T *type, argcontext_T *context) 243 arg_number(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
244 { 244 {
245 return check_arg_type(&t_number, type, context); 245 return check_arg_type(&t_number, type, context);
246 } 246 }
247 247
248 /* 248 /*
249 * Check "type" is a dict of 'any'. 249 * Check "type" is a dict of 'any'.
250 */ 250 */
251 static int 251 static int
252 arg_dict_any(type_T *type, argcontext_T *context) 252 arg_dict_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
253 { 253 {
254 return check_arg_type(&t_dict_any, type, context); 254 return check_arg_type(&t_dict_any, type, context);
255 } 255 }
256 256
257 /* 257 /*
258 * Check "type" is a list of 'any'. 258 * Check "type" is a list of 'any'.
259 */ 259 */
260 static int 260 static int
261 arg_list_any(type_T *type, argcontext_T *context) 261 arg_list_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
262 { 262 {
263 return check_arg_type(&t_list_any, type, context); 263 return check_arg_type(&t_list_any, type, context);
264 } 264 }
265 265
266 /* 266 /*
267 * Check "type" is a list of numbers. 267 * Check "type" is a list of numbers.
268 */ 268 */
269 static int 269 static int
270 arg_list_number(type_T *type, argcontext_T *context) 270 arg_list_number(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
271 { 271 {
272 return check_arg_type(&t_list_number, type, context); 272 return check_arg_type(&t_list_number, type, context);
273 } 273 }
274 274
275 /* 275 /*
276 * Check "type" is a list of strings. 276 * Check "type" is a list of strings.
277 */ 277 */
278 static int 278 static int
279 arg_list_string(type_T *type, argcontext_T *context) 279 arg_list_string(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
280 { 280 {
281 return check_arg_type(&t_list_string, type, context); 281 return check_arg_type(&t_list_string, type, context);
282 } 282 }
283 283
284 /* 284 /*
285 * Check "type" is a string. 285 * Check "type" is a string.
286 */ 286 */
287 static int 287 static int
288 arg_string(type_T *type, argcontext_T *context) 288 arg_string(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
289 { 289 {
290 return check_arg_type(&t_string, type, context); 290 return check_arg_type(&t_string, type, context);
291 } 291 }
292 292
293 /* 293 /*
294 * Check "type" is a blob 294 * Check "type" is a blob
295 */ 295 */
296 static int 296 static int
297 arg_blob(type_T *type, argcontext_T *context) 297 arg_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
298 { 298 {
299 return check_arg_type(&t_blob, type, context); 299 return check_arg_type(&t_blob, type, context);
300 } 300 }
301 301
302 /* 302 /*
303 * Check "type" is a bool or number 0 or 1. 303 * Check "type" is a bool or number 0 or 1.
304 */ 304 */
305 static int 305 static int
306 arg_bool(type_T *type, argcontext_T *context) 306 arg_bool(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
307 { 307 {
308 return check_arg_type(&t_bool, type, context); 308 return check_arg_type(&t_bool, type, context);
309 } 309 }
310 310
311 /* 311 /*
312 * Check "type" is a list of 'any' or a blob. 312 * Check "type" is a list of 'any' or a blob.
313 */ 313 */
314 static int 314 static int
315 arg_list_or_blob(type_T *type, argcontext_T *context) 315 arg_list_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
316 { 316 {
317 if (type->tt_type == VAR_ANY 317 if (type->tt_type == VAR_ANY
318 || type->tt_type == VAR_UNKNOWN 318 || type->tt_type == VAR_UNKNOWN
319 || type->tt_type == VAR_LIST 319 || type->tt_type == VAR_LIST
320 || type->tt_type == VAR_BLOB) 320 || type->tt_type == VAR_BLOB)
325 325
326 /* 326 /*
327 * Check "type" is a string or a number 327 * Check "type" is a string or a number
328 */ 328 */
329 static int 329 static int
330 arg_string_or_nr(type_T *type, argcontext_T *context) 330 arg_string_or_nr(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
331 { 331 {
332 if (type->tt_type == VAR_ANY 332 if (type->tt_type == VAR_ANY
333 || type->tt_type == VAR_UNKNOWN 333 || type->tt_type == VAR_UNKNOWN
334 || type->tt_type == VAR_STRING 334 || type->tt_type == VAR_STRING
335 || type->tt_type == VAR_NUMBER) 335 || type->tt_type == VAR_NUMBER)
340 340
341 /* 341 /*
342 * Check "type" is a buffer (string or a number) 342 * Check "type" is a buffer (string or a number)
343 */ 343 */
344 static int 344 static int
345 arg_buffer(type_T *type, argcontext_T *context) 345 arg_buffer(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
346 { 346 {
347 if (type->tt_type == VAR_ANY 347 if (type->tt_type == VAR_ANY
348 || type->tt_type == VAR_UNKNOWN 348 || type->tt_type == VAR_UNKNOWN
349 || type->tt_type == VAR_STRING 349 || type->tt_type == VAR_STRING
350 || type->tt_type == VAR_NUMBER) 350 || type->tt_type == VAR_NUMBER)
355 355
356 /* 356 /*
357 * Check "type" is a buffer or a dict of any 357 * Check "type" is a buffer or a dict of any
358 */ 358 */
359 static int 359 static int
360 arg_buffer_or_dict_any(type_T *type, argcontext_T *context) 360 arg_buffer_or_dict_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
361 { 361 {
362 if (type->tt_type == VAR_ANY 362 if (type->tt_type == VAR_ANY
363 || type->tt_type == VAR_UNKNOWN 363 || type->tt_type == VAR_UNKNOWN
364 || type->tt_type == VAR_STRING 364 || type->tt_type == VAR_STRING
365 || type->tt_type == VAR_NUMBER 365 || type->tt_type == VAR_NUMBER
371 371
372 /* 372 /*
373 * Check "type" is a line (string or a number) 373 * Check "type" is a line (string or a number)
374 */ 374 */
375 static int 375 static int
376 arg_lnum(type_T *type, argcontext_T *context) 376 arg_lnum(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
377 { 377 {
378 if (type->tt_type == VAR_ANY 378 if (type->tt_type == VAR_ANY
379 || type->tt_type == VAR_UNKNOWN 379 || type->tt_type == VAR_UNKNOWN
380 || type->tt_type == VAR_STRING 380 || type->tt_type == VAR_STRING
381 || type->tt_type == VAR_NUMBER) 381 || type->tt_type == VAR_NUMBER)
386 386
387 /* 387 /*
388 * Check "type" is a string or a list of strings. 388 * Check "type" is a string or a list of strings.
389 */ 389 */
390 static int 390 static int
391 arg_string_or_list_string(type_T *type, argcontext_T *context) 391 arg_string_or_list_string(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
392 { 392 {
393 if (type->tt_type == VAR_ANY 393 if (type->tt_type == VAR_ANY
394 || type->tt_type == VAR_UNKNOWN 394 || type->tt_type == VAR_UNKNOWN
395 || type->tt_type == VAR_STRING) 395 || type->tt_type == VAR_STRING)
396 return OK; 396 return OK;
409 409
410 /* 410 /*
411 * Check "type" is a string or a list of 'any' 411 * Check "type" is a string or a list of 'any'
412 */ 412 */
413 static int 413 static int
414 arg_string_or_list_any(type_T *type, argcontext_T *context) 414 arg_string_or_list_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
415 { 415 {
416 if (type->tt_type == VAR_ANY 416 if (type->tt_type == VAR_ANY
417 || type->tt_type == VAR_UNKNOWN 417 || type->tt_type == VAR_UNKNOWN
418 || type->tt_type == VAR_STRING 418 || type->tt_type == VAR_STRING
419 || type->tt_type == VAR_LIST) 419 || type->tt_type == VAR_LIST)
424 424
425 /* 425 /*
426 * Check "type" is a string or a blob 426 * Check "type" is a string or a blob
427 */ 427 */
428 static int 428 static int
429 arg_string_or_blob(type_T *type, argcontext_T *context) 429 arg_string_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
430 { 430 {
431 if (type->tt_type == VAR_ANY 431 if (type->tt_type == VAR_ANY
432 || type->tt_type == VAR_UNKNOWN 432 || type->tt_type == VAR_UNKNOWN
433 || type->tt_type == VAR_STRING 433 || type->tt_type == VAR_STRING
434 || type->tt_type == VAR_BLOB) 434 || type->tt_type == VAR_BLOB)
439 439
440 /* 440 /*
441 * Check "type" is a list of 'any' or a dict of 'any'. 441 * Check "type" is a list of 'any' or a dict of 'any'.
442 */ 442 */
443 static int 443 static int
444 arg_list_or_dict(type_T *type, argcontext_T *context) 444 arg_list_or_dict(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
445 { 445 {
446 if (type->tt_type == VAR_ANY 446 if (type->tt_type == VAR_ANY
447 || type->tt_type == VAR_UNKNOWN 447 || type->tt_type == VAR_UNKNOWN
448 || type->tt_type == VAR_LIST 448 || type->tt_type == VAR_LIST
449 || type->tt_type == VAR_DICT) 449 || type->tt_type == VAR_DICT)
454 454
455 /* 455 /*
456 * Check "type" is a list of 'any' or a dict of 'any' or a blob. 456 * Check "type" is a list of 'any' or a dict of 'any' or a blob.
457 */ 457 */
458 static int 458 static int
459 arg_list_or_dict_or_blob(type_T *type, argcontext_T *context) 459 arg_list_or_dict_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
460 { 460 {
461 if (type->tt_type == VAR_ANY 461 if (type->tt_type == VAR_ANY
462 || type->tt_type == VAR_UNKNOWN 462 || type->tt_type == VAR_UNKNOWN
463 || type->tt_type == VAR_LIST 463 || type->tt_type == VAR_LIST
464 || type->tt_type == VAR_DICT 464 || type->tt_type == VAR_DICT
470 470
471 /* 471 /*
472 * Check "type" is a list of 'any' or a dict of 'any' or a blob or a string. 472 * Check "type" is a list of 'any' or a dict of 'any' or a blob or a string.
473 */ 473 */
474 static int 474 static int
475 arg_list_or_dict_or_blob_or_string(type_T *type, argcontext_T *context) 475 arg_list_or_dict_or_blob_or_string(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
476 { 476 {
477 if (type->tt_type == VAR_ANY 477 if (type->tt_type == VAR_ANY
478 || type->tt_type == VAR_UNKNOWN 478 || type->tt_type == VAR_UNKNOWN
479 || type->tt_type == VAR_LIST 479 || type->tt_type == VAR_LIST
480 || type->tt_type == VAR_DICT 480 || type->tt_type == VAR_DICT
487 487
488 /* 488 /*
489 * Check second argument of filter(): func must return a bool. 489 * Check second argument of filter(): func must return a bool.
490 */ 490 */
491 static int 491 static int
492 arg_filter_func(type_T *type, argcontext_T *context) 492 arg_filter_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
493 { 493 {
494 if (type->tt_type == VAR_FUNC 494 if (type->tt_type == VAR_FUNC
495 && !(type->tt_member->tt_type == VAR_BOOL 495 && !(type->tt_member->tt_type == VAR_BOOL
496 || type->tt_member->tt_type == VAR_NUMBER 496 || type->tt_member->tt_type == VAR_NUMBER
497 || type->tt_member->tt_type == VAR_UNKNOWN 497 || type->tt_member->tt_type == VAR_UNKNOWN
505 505
506 /* 506 /*
507 * Check second argument of map(). 507 * Check second argument of map().
508 */ 508 */
509 static int 509 static int
510 arg_map_func(type_T *type, argcontext_T *context) 510 arg_map_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
511 { 511 {
512 if (type->tt_type == VAR_FUNC 512 if (type->tt_type == VAR_FUNC
513 && type->tt_member != &t_any 513 && type->tt_member != &t_any
514 && type->tt_member != &t_unknown) 514 && type->tt_member != &t_unknown)
515 { 515 {
516 type_T *expected = NULL; 516 type_T *expected = NULL;
517 517
518 if (context->arg_types[0]->tt_type == VAR_LIST 518 if (context->arg_types[0].type_curr->tt_type == VAR_LIST
519 || context->arg_types[0]->tt_type == VAR_DICT) 519 || context->arg_types[0].type_curr->tt_type == VAR_DICT)
520 expected = context->arg_types[0]->tt_member; 520 expected = context->arg_types[0].type_curr->tt_member;
521 else if (context->arg_types[0]->tt_type == VAR_STRING) 521 else if (context->arg_types[0].type_curr->tt_type == VAR_STRING)
522 expected = &t_string; 522 expected = &t_string;
523 else if (context->arg_types[0]->tt_type == VAR_BLOB) 523 else if (context->arg_types[0].type_curr->tt_type == VAR_BLOB)
524 expected = &t_number; 524 expected = &t_number;
525 if (expected != NULL) 525 if (expected != NULL)
526 { 526 {
527 type_T t_func_exp = {VAR_FUNC, -1, 0, TTFLAG_STATIC, 527 type_T t_func_exp = {VAR_FUNC, -1, 0, TTFLAG_STATIC,
528 expected, NULL}; 528 expected, NULL};
537 * Check an expression argument, can be a string, funcref or partial. 537 * Check an expression argument, can be a string, funcref or partial.
538 * Also accept a bool, a constant resulting from compiling a string argument. 538 * Also accept a bool, a constant resulting from compiling a string argument.
539 * Also accept a number, one and zero are accepted. 539 * Also accept a number, one and zero are accepted.
540 */ 540 */
541 static int 541 static int
542 arg_string_or_func(type_T *type, argcontext_T *context) 542 arg_string_or_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
543 { 543 {
544 if (type->tt_type == VAR_ANY 544 if (type->tt_type == VAR_ANY
545 || type->tt_type == VAR_UNKNOWN 545 || type->tt_type == VAR_UNKNOWN
546 || type->tt_type == VAR_STRING 546 || type->tt_type == VAR_STRING
547 || type->tt_type == VAR_PARTIAL 547 || type->tt_type == VAR_PARTIAL
555 555
556 /* 556 /*
557 * Check "type" is a list of 'any' or a blob or a string. 557 * Check "type" is a list of 'any' or a blob or a string.
558 */ 558 */
559 static int 559 static int
560 arg_string_list_or_blob(type_T *type, argcontext_T *context) 560 arg_string_list_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
561 { 561 {
562 if (type->tt_type == VAR_ANY 562 if (type->tt_type == VAR_ANY
563 || type->tt_type == VAR_UNKNOWN 563 || type->tt_type == VAR_UNKNOWN
564 || type->tt_type == VAR_LIST 564 || type->tt_type == VAR_LIST
565 || type->tt_type == VAR_BLOB 565 || type->tt_type == VAR_BLOB
571 571
572 /* 572 /*
573 * Check "type" is a job. 573 * Check "type" is a job.
574 */ 574 */
575 static int 575 static int
576 arg_job(type_T *type, argcontext_T *context) 576 arg_job(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
577 { 577 {
578 return check_arg_type(&t_job, type, context); 578 return check_arg_type(&t_job, type, context);
579 } 579 }
580 580
581 /* 581 /*
582 * Check "type" is a channel or a job. 582 * Check "type" is a channel or a job.
583 */ 583 */
584 static int 584 static int
585 arg_chan_or_job(type_T *type, argcontext_T *context) 585 arg_chan_or_job(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
586 { 586 {
587 if (type->tt_type == VAR_ANY 587 if (type->tt_type == VAR_ANY
588 || type->tt_type == VAR_UNKNOWN 588 || type->tt_type == VAR_UNKNOWN
589 || type->tt_type == VAR_CHANNEL 589 || type->tt_type == VAR_CHANNEL
590 || type->tt_type == VAR_JOB) 590 || type->tt_type == VAR_JOB)
592 arg_type_mismatch(&t_channel, type, context->arg_idx + 1); 592 arg_type_mismatch(&t_channel, type, context->arg_idx + 1);
593 return FAIL; 593 return FAIL;
594 } 594 }
595 595
596 /* 596 /*
597 * Check "type" is the same type as the previous argument. 597 * Check "type" can be used as the type_decl of the previous argument.
598 * Must not be used for the first argcheck_T entry. 598 * Must not be used for the first argcheck_T entry.
599 */ 599 */
600 static int 600 static int
601 arg_same_as_prev(type_T *type, argcontext_T *context) 601 arg_same_as_prev(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
602 { 602 {
603 type_T *prev_type = context->arg_types[context->arg_idx - 1]; 603 type_T *prev_type = context->arg_types[context->arg_idx - 1].type_decl;
604 604
605 return check_arg_type(prev_type, type, context); 605 return check_arg_type(prev_type, type, context);
606 } 606 }
607 607
608 /* 608 /*
609 * Check "type" is the same basic type as the previous argument, checks list or 609 * Check "type" is the same basic type as the previous argument, checks list or
610 * dict vs other type, but not member type. 610 * dict vs other type, but not member type.
611 * Must not be used for the first argcheck_T entry. 611 * Must not be used for the first argcheck_T entry.
612 */ 612 */
613 static int 613 static int
614 arg_same_struct_as_prev(type_T *type, argcontext_T *context) 614 arg_same_struct_as_prev(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
615 { 615 {
616 type_T *prev_type = context->arg_types[context->arg_idx - 1]; 616 type_T *prev_type = context->arg_types[context->arg_idx - 1].type_curr;
617 617
618 if (prev_type->tt_type != context->arg_types[context->arg_idx]->tt_type) 618 if (prev_type->tt_type != context->arg_types[context->arg_idx].type_curr->tt_type)
619 return check_arg_type(prev_type, type, context); 619 return check_arg_type(prev_type, type, context);
620 return OK; 620 return OK;
621 } 621 }
622 622
623 /* 623 /*
624 * Check "type" is an item of the list or blob of the previous arg. 624 * Check "type" is an item of the list or blob of the previous arg.
625 * Must not be used for the first argcheck_T entry. 625 * Must not be used for the first argcheck_T entry.
626 */ 626 */
627 static int 627 static int
628 arg_item_of_prev(type_T *type, argcontext_T *context) 628 arg_item_of_prev(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
629 { 629 {
630 type_T *prev_type = context->arg_types[context->arg_idx - 1]; 630 type_T *prev_type = context->arg_types[context->arg_idx - 1].type_curr;
631 type_T *expected; 631 type_T *expected;
632 632
633 if (prev_type->tt_type == VAR_LIST) 633 if (prev_type->tt_type == VAR_LIST)
634 expected = prev_type->tt_member; 634 expected = prev_type->tt_member;
635 else if (prev_type->tt_type == VAR_BLOB) 635 else if (prev_type->tt_type == VAR_BLOB)
643 643
644 /* 644 /*
645 * Check "type" is a string or a number or a list 645 * Check "type" is a string or a number or a list
646 */ 646 */
647 static int 647 static int
648 arg_str_or_nr_or_list(type_T *type, argcontext_T *context) 648 arg_str_or_nr_or_list(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
649 { 649 {
650 if (type->tt_type == VAR_ANY 650 if (type->tt_type == VAR_ANY
651 || type->tt_type == VAR_UNKNOWN 651 || type->tt_type == VAR_UNKNOWN
652 || type->tt_type == VAR_STRING 652 || type->tt_type == VAR_STRING
653 || type->tt_type == VAR_NUMBER 653 || type->tt_type == VAR_NUMBER
659 659
660 /* 660 /*
661 * Check "type" is a dict of 'any' or a string 661 * Check "type" is a dict of 'any' or a string
662 */ 662 */
663 static int 663 static int
664 arg_dict_any_or_string(type_T *type, argcontext_T *context) 664 arg_dict_any_or_string(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
665 { 665 {
666 if (type->tt_type == VAR_ANY 666 if (type->tt_type == VAR_ANY
667 || type->tt_type == VAR_UNKNOWN 667 || type->tt_type == VAR_UNKNOWN
668 || type->tt_type == VAR_DICT 668 || type->tt_type == VAR_DICT
669 || type->tt_type == VAR_STRING) 669 || type->tt_type == VAR_STRING)
675 /* 675 /*
676 * Check "type" which is the third argument of extend() (number or string or 676 * Check "type" which is the third argument of extend() (number or string or
677 * any) 677 * any)
678 */ 678 */
679 static int 679 static int
680 arg_extend3(type_T *type, argcontext_T *context) 680 arg_extend3(type_T *type, type_T *decl_type, argcontext_T *context)
681 { 681 {
682 type_T *first_type = context->arg_types[context->arg_idx - 2]; 682 type_T *first_type = context->arg_types[context->arg_idx - 2].type_curr;
683 683
684 if (first_type->tt_type == VAR_LIST) 684 if (first_type->tt_type == VAR_LIST)
685 return arg_number(type, context); 685 return arg_number(type, decl_type, context);
686 if (first_type->tt_type == VAR_DICT) 686 if (first_type->tt_type == VAR_DICT)
687 return arg_string(type, context); 687 return arg_string(type, decl_type, context);
688 return OK; 688 return OK;
689 } 689 }
690 690
691 /* 691 /*
692 * Check "type" which is the first argument of get() (blob or list or dict or 692 * Check "type" which is the first argument of get() (blob or list or dict or
693 * funcref) 693 * funcref)
694 */ 694 */
695 static int 695 static int
696 arg_get1(type_T *type, argcontext_T *context) 696 arg_get1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
697 { 697 {
698 if (type->tt_type == VAR_ANY 698 if (type->tt_type == VAR_ANY
699 || type->tt_type == VAR_UNKNOWN 699 || type->tt_type == VAR_UNKNOWN
700 || type->tt_type == VAR_BLOB 700 || type->tt_type == VAR_BLOB
701 || type->tt_type == VAR_LIST 701 || type->tt_type == VAR_LIST
711 /* 711 /*
712 * Check "type" which is the first argument of len() (number or string or 712 * Check "type" which is the first argument of len() (number or string or
713 * blob or list or dict) 713 * blob or list or dict)
714 */ 714 */
715 static int 715 static int
716 arg_len1(type_T *type, argcontext_T *context) 716 arg_len1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
717 { 717 {
718 if (type->tt_type == VAR_ANY 718 if (type->tt_type == VAR_ANY
719 || type->tt_type == VAR_UNKNOWN 719 || type->tt_type == VAR_UNKNOWN
720 || type->tt_type == VAR_STRING 720 || type->tt_type == VAR_STRING
721 || type->tt_type == VAR_NUMBER 721 || type->tt_type == VAR_NUMBER
731 /* 731 /*
732 * Check "type" which is the second argument of remove() (number or string or 732 * Check "type" which is the second argument of remove() (number or string or
733 * any) 733 * any)
734 */ 734 */
735 static int 735 static int
736 arg_remove2(type_T *type, argcontext_T *context) 736 arg_remove2(type_T *type, type_T *decl_type, argcontext_T *context)
737 { 737 {
738 type_T *first_type = context->arg_types[context->arg_idx - 1]; 738 type_T *first_type = context->arg_types[context->arg_idx - 1].type_curr;
739 739
740 if (first_type->tt_type == VAR_LIST || first_type->tt_type == VAR_BLOB) 740 if (first_type->tt_type == VAR_LIST || first_type->tt_type == VAR_BLOB)
741 return arg_number(type, context); 741 return arg_number(type, decl_type, context);
742 if (first_type->tt_type == VAR_DICT) 742 if (first_type->tt_type == VAR_DICT)
743 return arg_string_or_nr(type, context); 743 return arg_string_or_nr(type, decl_type, context);
744 return OK; 744 return OK;
745 } 745 }
746 746
747 /* 747 /*
748 * Check "type" which is the first argument of repeat() (string or number or 748 * Check "type" which is the first argument of repeat() (string or number or
749 * list or any) 749 * list or any)
750 */ 750 */
751 static int 751 static int
752 arg_repeat1(type_T *type, argcontext_T *context) 752 arg_repeat1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
753 { 753 {
754 if (type->tt_type == VAR_ANY 754 if (type->tt_type == VAR_ANY
755 || type->tt_type == VAR_UNKNOWN 755 || type->tt_type == VAR_UNKNOWN
756 || type->tt_type == VAR_STRING 756 || type->tt_type == VAR_STRING
757 || type->tt_type == VAR_NUMBER 757 || type->tt_type == VAR_NUMBER
765 /* 765 /*
766 * Check "type" which is the first argument of slice() (list or blob or string 766 * Check "type" which is the first argument of slice() (list or blob or string
767 * or any) 767 * or any)
768 */ 768 */
769 static int 769 static int
770 arg_slice1(type_T *type, argcontext_T *context) 770 arg_slice1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
771 { 771 {
772 if (type->tt_type == VAR_ANY 772 if (type->tt_type == VAR_ANY
773 || type->tt_type == VAR_UNKNOWN 773 || type->tt_type == VAR_UNKNOWN
774 || type->tt_type == VAR_LIST 774 || type->tt_type == VAR_LIST
775 || type->tt_type == VAR_BLOB 775 || type->tt_type == VAR_BLOB
783 /* 783 /*
784 * Check "type" which is the first argument of count() (string or list or dict 784 * Check "type" which is the first argument of count() (string or list or dict
785 * or any) 785 * or any)
786 */ 786 */
787 static int 787 static int
788 arg_count1(type_T *type, argcontext_T *context) 788 arg_count1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
789 { 789 {
790 if (type->tt_type == VAR_ANY 790 if (type->tt_type == VAR_ANY
791 || type->tt_type == VAR_UNKNOWN 791 || type->tt_type == VAR_UNKNOWN
792 || type->tt_type == VAR_STRING 792 || type->tt_type == VAR_STRING
793 || type->tt_type == VAR_LIST 793 || type->tt_type == VAR_LIST
801 /* 801 /*
802 * Check "type" which is the first argument of cursor() (number or string or 802 * Check "type" which is the first argument of cursor() (number or string or
803 * list or any) 803 * list or any)
804 */ 804 */
805 static int 805 static int
806 arg_cursor1(type_T *type, argcontext_T *context) 806 arg_cursor1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
807 { 807 {
808 if (type->tt_type == VAR_ANY 808 if (type->tt_type == VAR_ANY
809 || type->tt_type == VAR_UNKNOWN 809 || type->tt_type == VAR_UNKNOWN
810 || type->tt_type == VAR_NUMBER 810 || type->tt_type == VAR_NUMBER
811 || type->tt_type == VAR_STRING 811 || type->tt_type == VAR_STRING
958 /* 958 /*
959 * Functions that return the return type of a builtin function. 959 * Functions that return the return type of a builtin function.
960 * Note that "argtypes" is NULL if "argcount" is zero. 960 * Note that "argtypes" is NULL if "argcount" is zero.
961 */ 961 */
962 static type_T * 962 static type_T *
963 ret_void(int argcount UNUSED, type_T **argtypes UNUSED) 963 ret_void(int argcount UNUSED, type2_T *argtypes UNUSED)
964 { 964 {
965 return &t_void; 965 return &t_void;
966 } 966 }
967 static type_T * 967 static type_T *
968 ret_any(int argcount UNUSED, type_T **argtypes UNUSED) 968 ret_any(int argcount UNUSED, type2_T *argtypes UNUSED)
969 { 969 {
970 return &t_any; 970 return &t_any;
971 } 971 }
972 static type_T * 972 static type_T *
973 ret_bool(int argcount UNUSED, type_T **argtypes UNUSED) 973 ret_bool(int argcount UNUSED, type2_T *argtypes UNUSED)
974 { 974 {
975 return &t_bool; 975 return &t_bool;
976 } 976 }
977 static type_T * 977 static type_T *
978 ret_number_bool(int argcount UNUSED, type_T **argtypes UNUSED) 978 ret_number_bool(int argcount UNUSED, type2_T *argtypes UNUSED)
979 { 979 {
980 return &t_number_bool; 980 return &t_number_bool;
981 } 981 }
982 static type_T * 982 static type_T *
983 ret_number(int argcount UNUSED, type_T **argtypes UNUSED) 983 ret_number(int argcount UNUSED, type2_T *argtypes UNUSED)
984 { 984 {
985 return &t_number; 985 return &t_number;
986 } 986 }
987 static type_T * 987 static type_T *
988 ret_float(int argcount UNUSED, type_T **argtypes UNUSED) 988 ret_float(int argcount UNUSED, type2_T *argtypes UNUSED)
989 { 989 {
990 return &t_float; 990 return &t_float;
991 } 991 }
992 static type_T * 992 static type_T *
993 ret_string(int argcount UNUSED, type_T **argtypes UNUSED) 993 ret_string(int argcount UNUSED, type2_T *argtypes UNUSED)
994 { 994 {
995 return &t_string; 995 return &t_string;
996 } 996 }
997 static type_T * 997 static type_T *
998 ret_list_any(int argcount UNUSED, type_T **argtypes UNUSED) 998 ret_list_any(int argcount UNUSED, type2_T *argtypes UNUSED)
999 { 999 {
1000 return &t_list_any; 1000 return &t_list_any;
1001 } 1001 }
1002 static type_T * 1002 static type_T *
1003 ret_list_number(int argcount UNUSED, type_T **argtypes UNUSED) 1003 ret_list_number(int argcount UNUSED, type2_T *argtypes UNUSED)
1004 { 1004 {
1005 return &t_list_number; 1005 return &t_list_number;
1006 } 1006 }
1007 static type_T * 1007 static type_T *
1008 ret_list_string(int argcount UNUSED, type_T **argtypes UNUSED) 1008 ret_list_string(int argcount UNUSED, type2_T *argtypes UNUSED)
1009 { 1009 {
1010 return &t_list_string; 1010 return &t_list_string;
1011 } 1011 }
1012 static type_T * 1012 static type_T *
1013 ret_list_dict_any(int argcount UNUSED, type_T **argtypes UNUSED) 1013 ret_list_dict_any(int argcount UNUSED, type2_T *argtypes UNUSED)
1014 { 1014 {
1015 return &t_list_dict_any; 1015 return &t_list_dict_any;
1016 } 1016 }
1017 static type_T * 1017 static type_T *
1018 ret_list_items(int argcount UNUSED, type_T **argtypes UNUSED) 1018 ret_list_items(int argcount UNUSED, type2_T *argtypes UNUSED)
1019 { 1019 {
1020 return &t_list_list_any; 1020 return &t_list_list_any;
1021 } 1021 }
1022 1022
1023 static type_T * 1023 static type_T *
1024 ret_list_string_items(int argcount UNUSED, type_T **argtypes UNUSED) 1024 ret_list_string_items(int argcount UNUSED, type2_T *argtypes UNUSED)
1025 { 1025 {
1026 return &t_list_list_string; 1026 return &t_list_list_string;
1027 } 1027 }
1028 static type_T * 1028 static type_T *
1029 ret_dict_any(int argcount UNUSED, type_T **argtypes UNUSED) 1029 ret_dict_any(int argcount UNUSED, type2_T *argtypes UNUSED)
1030 { 1030 {
1031 return &t_dict_any; 1031 return &t_dict_any;
1032 } 1032 }
1033 static type_T * 1033 static type_T *
1034 ret_job_info(int argcount, type_T **argtypes UNUSED) 1034 ret_job_info(int argcount, type2_T *argtypes UNUSED)
1035 { 1035 {
1036 if (argcount == 0) 1036 if (argcount == 0)
1037 return &t_list_job; 1037 return &t_list_job;
1038 return &t_dict_any; 1038 return &t_dict_any;
1039 } 1039 }
1040 static type_T * 1040 static type_T *
1041 ret_dict_number(int argcount UNUSED, type_T **argtypes UNUSED) 1041 ret_dict_number(int argcount UNUSED, type2_T *argtypes UNUSED)
1042 { 1042 {
1043 return &t_dict_number; 1043 return &t_dict_number;
1044 } 1044 }
1045 static type_T * 1045 static type_T *
1046 ret_dict_string(int argcount UNUSED, type_T **argtypes UNUSED) 1046 ret_dict_string(int argcount UNUSED, type2_T *argtypes UNUSED)
1047 { 1047 {
1048 return &t_dict_string; 1048 return &t_dict_string;
1049 } 1049 }
1050 static type_T * 1050 static type_T *
1051 ret_blob(int argcount UNUSED, type_T **argtypes UNUSED) 1051 ret_blob(int argcount UNUSED, type2_T *argtypes UNUSED)
1052 { 1052 {
1053 return &t_blob; 1053 return &t_blob;
1054 } 1054 }
1055 static type_T * 1055 static type_T *
1056 ret_func_any(int argcount UNUSED, type_T **argtypes UNUSED) 1056 ret_func_any(int argcount UNUSED, type2_T *argtypes UNUSED)
1057 { 1057 {
1058 return &t_func_any; 1058 return &t_func_any;
1059 } 1059 }
1060 static type_T * 1060 static type_T *
1061 ret_func_unknown(int argcount UNUSED, type_T **argtypes UNUSED) 1061 ret_func_unknown(int argcount UNUSED, type2_T *argtypes UNUSED)
1062 { 1062 {
1063 return &t_func_unknown; 1063 return &t_func_unknown;
1064 } 1064 }
1065 static type_T * 1065 static type_T *
1066 ret_channel(int argcount UNUSED, type_T **argtypes UNUSED) 1066 ret_channel(int argcount UNUSED, type2_T *argtypes UNUSED)
1067 { 1067 {
1068 return &t_channel; 1068 return &t_channel;
1069 } 1069 }
1070 static type_T * 1070 static type_T *
1071 ret_job(int argcount UNUSED, type_T **argtypes UNUSED) 1071 ret_job(int argcount UNUSED, type2_T *argtypes UNUSED)
1072 { 1072 {
1073 return &t_job; 1073 return &t_job;
1074 } 1074 }
1075 static type_T * 1075 static type_T *
1076 ret_first_arg(int argcount, type_T **argtypes) 1076 ret_first_arg(int argcount, type2_T *argtypes)
1077 { 1077 {
1078 if (argcount > 0) 1078 if (argcount > 0)
1079 return argtypes[0]; 1079 return argtypes[0].type_curr;
1080 return &t_void; 1080 return &t_void;
1081 } 1081 }
1082 static type_T * 1082 static type_T *
1083 ret_repeat(int argcount, type_T **argtypes) 1083 ret_repeat(int argcount, type2_T *argtypes)
1084 { 1084 {
1085 if (argcount == 0) 1085 if (argcount == 0)
1086 return &t_any; 1086 return &t_any;
1087 if (argtypes[0] == &t_number) 1087 if (argtypes[0].type_curr == &t_number)
1088 return &t_string; 1088 return &t_string;
1089 return argtypes[0]; 1089 return argtypes[0].type_curr;
1090 } 1090 }
1091 // for map(): returns first argument but item type may differ 1091 // for map(): returns first argument but item type may differ
1092 static type_T * 1092 static type_T *
1093 ret_first_cont(int argcount, type_T **argtypes) 1093 ret_first_cont(int argcount, type2_T *argtypes)
1094 { 1094 {
1095 if (argcount > 0) 1095 if (argcount > 0)
1096 { 1096 {
1097 if (argtypes[0]->tt_type == VAR_LIST) 1097 if (argtypes[0].type_curr->tt_type == VAR_LIST)
1098 return &t_list_any; 1098 return &t_list_any;
1099 if (argtypes[0]->tt_type == VAR_DICT) 1099 if (argtypes[0].type_curr->tt_type == VAR_DICT)
1100 return &t_dict_any; 1100 return &t_dict_any;
1101 if (argtypes[0]->tt_type == VAR_BLOB) 1101 if (argtypes[0].type_curr->tt_type == VAR_BLOB)
1102 return argtypes[0]; 1102 return argtypes[0].type_curr;
1103 } 1103 }
1104 return &t_any; 1104 return &t_any;
1105 }
1106 // for getline()
1107 static type_T *
1108 ret_getline(int argcount, type2_T *argtypes UNUSED)
1109 {
1110 return argcount == 1 ? &t_string : &t_list_string;
1105 } 1111 }
1106 // for finddir() 1112 // for finddir()
1107 static type_T * 1113 static type_T *
1108 ret_finddir(int argcount, type_T **argtypes UNUSED) 1114 ret_finddir(int argcount, type2_T *argtypes UNUSED)
1109 { 1115 {
1110 if (argcount < 3) 1116 if (argcount < 3)
1111 return &t_string; 1117 return &t_string;
1112 // Depending on the count would be a string or a list of strings. 1118 // Depending on the count would be a string or a list of strings.
1113 return &t_any; 1119 return &t_any;
1116 /* 1122 /*
1117 * Used for getqflist(): returns list if there is no argument, dict if there is 1123 * Used for getqflist(): returns list if there is no argument, dict if there is
1118 * one. 1124 * one.
1119 */ 1125 */
1120 static type_T * 1126 static type_T *
1121 ret_list_or_dict_0(int argcount, type_T **argtypes UNUSED) 1127 ret_list_or_dict_0(int argcount, type2_T *argtypes UNUSED)
1122 { 1128 {
1123 if (argcount > 0) 1129 if (argcount > 0)
1124 return &t_dict_any; 1130 return &t_dict_any;
1125 return &t_list_dict_any; 1131 return &t_list_dict_any;
1126 } 1132 }
1128 /* 1134 /*
1129 * Used for getloclist(): returns list if there is one argument, dict if there 1135 * Used for getloclist(): returns list if there is one argument, dict if there
1130 * are two. 1136 * are two.
1131 */ 1137 */
1132 static type_T * 1138 static type_T *
1133 ret_list_or_dict_1(int argcount, type_T **argtypes UNUSED) 1139 ret_list_or_dict_1(int argcount, type2_T *argtypes UNUSED)
1134 { 1140 {
1135 if (argcount > 1) 1141 if (argcount > 1)
1136 return &t_dict_any; 1142 return &t_dict_any;
1137 return &t_list_dict_any; 1143 return &t_list_dict_any;
1138 } 1144 }
1139 1145
1140 static type_T * 1146 static type_T *
1141 ret_argv(int argcount, type_T **argtypes UNUSED) 1147 ret_argv(int argcount, type2_T *argtypes UNUSED)
1142 { 1148 {
1143 // argv() returns list of strings 1149 // argv() returns list of strings
1144 if (argcount == 0) 1150 if (argcount == 0)
1145 return &t_list_string; 1151 return &t_list_string;
1146 1152
1147 // argv(0) returns a string, but argv(-1] returns a list 1153 // argv(0) returns a string, but argv(-1] returns a list
1148 return &t_any; 1154 return &t_any;
1149 } 1155 }
1150 1156
1151 static type_T * 1157 static type_T *
1152 ret_remove(int argcount, type_T **argtypes) 1158 ret_remove(int argcount, type2_T *argtypes)
1153 { 1159 {
1154 if (argcount > 0) 1160 if (argcount > 0)
1155 { 1161 {
1156 if (argtypes[0]->tt_type == VAR_LIST 1162 if (argtypes[0].type_curr->tt_type == VAR_LIST
1157 || argtypes[0]->tt_type == VAR_DICT) 1163 || argtypes[0].type_curr->tt_type == VAR_DICT)
1158 return argtypes[0]->tt_member; 1164 return argtypes[0].type_curr->tt_member;
1159 if (argtypes[0]->tt_type == VAR_BLOB) 1165 if (argtypes[0].type_curr->tt_type == VAR_BLOB)
1160 return &t_number; 1166 return &t_number;
1161 } 1167 }
1162 return &t_any; 1168 return &t_any;
1163 } 1169 }
1164 1170
1165 static type_T * 1171 static type_T *
1166 ret_getreg(int argcount, type_T **argtypes UNUSED) 1172 ret_getreg(int argcount, type2_T *argtypes UNUSED)
1167 { 1173 {
1168 // Assume that if the third argument is passed it's non-zero 1174 // Assume that if the third argument is passed it's non-zero
1169 if (argcount == 3) 1175 if (argcount == 3)
1170 return &t_list_string; 1176 return &t_list_string;
1171 return &t_string; 1177 return &t_string;
1172 } 1178 }
1173 1179
1174 static type_T * 1180 static type_T *
1175 ret_maparg(int argcount, type_T **argtypes UNUSED) 1181 ret_maparg(int argcount, type2_T *argtypes UNUSED)
1176 { 1182 {
1177 // Assume that if the fourth argument is passed it's non-zero 1183 // Assume that if the fourth argument is passed it's non-zero
1178 if (argcount == 4) 1184 if (argcount == 4)
1179 return &t_dict_any; 1185 return &t_dict_any;
1180 return &t_string; 1186 return &t_string;
1189 char *f_name; // function name 1195 char *f_name; // function name
1190 char f_min_argc; // minimal number of arguments 1196 char f_min_argc; // minimal number of arguments
1191 char f_max_argc; // maximal number of arguments 1197 char f_max_argc; // maximal number of arguments
1192 char f_argtype; // for method: FEARG_ values 1198 char f_argtype; // for method: FEARG_ values
1193 argcheck_T *f_argcheck; // list of functions to check argument types 1199 argcheck_T *f_argcheck; // list of functions to check argument types
1194 type_T *(*f_retfunc)(int argcount, type_T **argtypes); 1200 type_T *(*f_retfunc)(int argcount, type2_T *argtypes);
1195 // return type function 1201 // return type function
1196 void (*f_func)(typval_T *args, typval_T *rvar); 1202 void (*f_func)(typval_T *args, typval_T *rvar);
1197 // implementation of function 1203 // implementation of function
1198 } funcentry_T; 1204 } funcentry_T;
1199 1205
1597 {"getimstatus", 0, 0, 0, NULL, 1603 {"getimstatus", 0, 0, 0, NULL,
1598 ret_number_bool, f_getimstatus}, 1604 ret_number_bool, f_getimstatus},
1599 {"getjumplist", 0, 2, FEARG_1, arg2_number, 1605 {"getjumplist", 0, 2, FEARG_1, arg2_number,
1600 ret_list_any, f_getjumplist}, 1606 ret_list_any, f_getjumplist},
1601 {"getline", 1, 2, FEARG_1, arg2_lnum, 1607 {"getline", 1, 2, FEARG_1, arg2_lnum,
1602 ret_f_getline, f_getline}, 1608 ret_getline, f_getline},
1603 {"getloclist", 1, 2, 0, arg2_number_dict_any, 1609 {"getloclist", 1, 2, 0, arg2_number_dict_any,
1604 ret_list_or_dict_1, f_getloclist}, 1610 ret_list_or_dict_1, f_getloclist},
1605 {"getmarklist", 0, 1, FEARG_1, arg1_buffer, 1611 {"getmarklist", 0, 1, FEARG_1, arg1_buffer,
1606 ret_list_dict_any, f_getmarklist}, 1612 ret_list_dict_any, f_getmarklist},
1607 {"getmatches", 0, 1, 0, arg1_number, 1613 {"getmatches", 0, 1, 0, arg1_number,
2574 * Uses the list of types on the type stack: "types". 2580 * Uses the list of types on the type stack: "types".
2575 * Return FAIL and gives an error message when a type is wrong. 2581 * Return FAIL and gives an error message when a type is wrong.
2576 */ 2582 */
2577 int 2583 int
2578 internal_func_check_arg_types( 2584 internal_func_check_arg_types(
2579 type_T **types, 2585 type2_T *types,
2580 int idx, 2586 int idx,
2581 int argcount, 2587 int argcount,
2582 cctx_T *cctx) 2588 cctx_T *cctx)
2583 { 2589 {
2584 argcheck_T *argchecks = global_functions[idx].f_argcheck; 2590 argcheck_T *argchecks = global_functions[idx].f_argcheck;
2593 context.arg_cctx = cctx; 2599 context.arg_cctx = cctx;
2594 for (i = 0; i < argcount; ++i) 2600 for (i = 0; i < argcount; ++i)
2595 if (argchecks[i] != NULL) 2601 if (argchecks[i] != NULL)
2596 { 2602 {
2597 context.arg_idx = i; 2603 context.arg_idx = i;
2598 if (argchecks[i](types[i], &context) == FAIL) 2604 if (argchecks[i](types[i].type_curr, types[i].type_decl,
2605 &context) == FAIL)
2599 return FAIL; 2606 return FAIL;
2600 } 2607 }
2601 } 2608 }
2602 return OK; 2609 return OK;
2603 } 2610 }
2619 * "argtypes" is the list of argument types or NULL when there are no 2626 * "argtypes" is the list of argument types or NULL when there are no
2620 * arguments. 2627 * arguments.
2621 * "argcount" may be less than the actual count when only getting the type. 2628 * "argcount" may be less than the actual count when only getting the type.
2622 */ 2629 */
2623 type_T * 2630 type_T *
2624 internal_func_ret_type(int idx, int argcount, type_T **argtypes) 2631 internal_func_ret_type(int idx, int argcount, type2_T *argtypes)
2625 { 2632 {
2626 return global_functions[idx].f_retfunc(argcount, argtypes); 2633 return global_functions[idx].f_retfunc(argcount, argtypes);
2627 } 2634 }
2628 2635
2629 /* 2636 /*