Mercurial > vim
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 /* |