Mercurial > vim
comparison src/userfunc.c @ 23332:cdb706d5c43d v8.2.2209
patch 8.2.2209: Vim9: return type of => lambda not parsed
Commit: https://github.com/vim/vim/commit/9e68c32563d8c9ffe1ac04ecd4ccd730af66b97c
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Dec 25 12:38:04 2020 +0100
patch 8.2.2209: Vim9: return type of => lambda not parsed
Problem: Vim9: return type of => lambda not parsed.
Solution: Parse and use the return type.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 25 Dec 2020 12:45:05 +0100 |
parents | 1d11e3adbe52 |
children | 9c5275b1c763 |
comparison
equal
deleted
inserted
replaced
23331:c5b1246b9557 | 23332:cdb706d5c43d |
---|---|
347 | 347 |
348 if (p == NULL) | 348 if (p == NULL) |
349 // will get the type from the default value | 349 // will get the type from the default value |
350 type = &t_unknown; | 350 type = &t_unknown; |
351 else | 351 else |
352 type = parse_type(&p, &fp->uf_type_list); | 352 type = parse_type(&p, &fp->uf_type_list, TRUE); |
353 if (type == NULL) | 353 if (type == NULL) |
354 return FAIL; | 354 return FAIL; |
355 fp->uf_arg_types[i] = type; | 355 fp->uf_arg_types[i] = type; |
356 } | 356 } |
357 } | 357 } |
367 p = ((char_u **)argtypes->ga_data)[len]; | 367 p = ((char_u **)argtypes->ga_data)[len]; |
368 if (p == NULL) | 368 if (p == NULL) |
369 // todo: get type from default value | 369 // todo: get type from default value |
370 fp->uf_va_type = &t_any; | 370 fp->uf_va_type = &t_any; |
371 else | 371 else |
372 fp->uf_va_type = parse_type(&p, &fp->uf_type_list); | 372 fp->uf_va_type = parse_type(&p, &fp->uf_type_list, TRUE); |
373 if (fp->uf_va_type == NULL) | 373 if (fp->uf_va_type == NULL) |
374 return FAIL; | 374 return FAIL; |
375 } | 375 } |
376 } | 376 } |
377 return OK; | 377 return OK; |
458 } | 458 } |
459 #endif | 459 #endif |
460 | 460 |
461 /* | 461 /* |
462 * Skip over "->" or "=>" after the arguments of a lambda. | 462 * Skip over "->" or "=>" after the arguments of a lambda. |
463 * If ": type" is found make "ret_type" point to "type". | |
463 * Return NULL if no valid arrow found. | 464 * Return NULL if no valid arrow found. |
464 */ | 465 */ |
465 static char_u * | 466 static char_u * |
466 skip_arrow(char_u *start, int equal_arrow) | 467 skip_arrow(char_u *start, int equal_arrow, char_u **ret_type) |
467 { | 468 { |
468 char_u *s = start; | 469 char_u *s = start; |
469 | 470 |
470 if (equal_arrow) | 471 if (equal_arrow) |
471 { | 472 { |
472 if (*s == ':') | 473 if (*s == ':') |
473 s = skip_type(skipwhite(s + 1), TRUE); | 474 { |
475 s = skipwhite(s + 1); | |
476 *ret_type = s; | |
477 s = skip_type(s, TRUE); | |
478 } | |
474 s = skipwhite(s); | 479 s = skipwhite(s); |
475 if (*s != '=') | 480 if (*s != '=') |
476 return NULL; | 481 return NULL; |
477 ++s; | 482 ++s; |
478 } | 483 } |
501 garray_T *pnewargs; | 506 garray_T *pnewargs; |
502 garray_T argtypes; | 507 garray_T argtypes; |
503 ufunc_T *fp = NULL; | 508 ufunc_T *fp = NULL; |
504 partial_T *pt = NULL; | 509 partial_T *pt = NULL; |
505 int varargs; | 510 int varargs; |
511 char_u *ret_type = NULL; | |
506 int ret; | 512 int ret; |
507 char_u *s; | 513 char_u *s; |
508 char_u *start, *end; | 514 char_u *start, *end; |
509 int *old_eval_lavars = eval_lavars_used; | 515 int *old_eval_lavars = eval_lavars_used; |
510 int eval_lavars = FALSE; | 516 int eval_lavars = FALSE; |
515 return NOTDONE; | 521 return NOTDONE; |
516 | 522 |
517 ga_init(&newargs); | 523 ga_init(&newargs); |
518 ga_init(&newlines); | 524 ga_init(&newlines); |
519 | 525 |
520 // First, check if this is a lambda expression. "->" or "=>" must exist. | 526 // First, check if this is really a lambda expression. "->" or "=>" must |
527 // be found after the arguments. | |
521 s = skipwhite(*arg + 1); | 528 s = skipwhite(*arg + 1); |
522 ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL, | 529 ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL, |
523 types_optional ? &argtypes : NULL, types_optional, | 530 types_optional ? &argtypes : NULL, types_optional, |
524 NULL, NULL, TRUE, NULL, NULL); | 531 NULL, NULL, TRUE, NULL, NULL); |
525 if (ret == FAIL || skip_arrow(s, equal_arrow) == NULL) | 532 if (ret == FAIL || skip_arrow(s, equal_arrow, &ret_type) == NULL) |
526 { | 533 { |
527 if (types_optional) | 534 if (types_optional) |
528 ga_clear_strings(&argtypes); | 535 ga_clear_strings(&argtypes); |
529 return NOTDONE; | 536 return NOTDONE; |
530 } | 537 } |
531 | 538 |
532 // Parse the arguments again. | 539 // Parse the arguments for real. |
533 if (evaluate) | 540 if (evaluate) |
534 pnewargs = &newargs; | 541 pnewargs = &newargs; |
535 else | 542 else |
536 pnewargs = NULL; | 543 pnewargs = NULL; |
537 *arg = skipwhite(*arg + 1); | 544 *arg = skipwhite(*arg + 1); |
538 ret = get_function_args(arg, equal_arrow ? ')' : '-', pnewargs, | 545 ret = get_function_args(arg, equal_arrow ? ')' : '-', pnewargs, |
539 types_optional ? &argtypes : NULL, types_optional, | 546 types_optional ? &argtypes : NULL, types_optional, |
540 &varargs, NULL, FALSE, NULL, NULL); | 547 &varargs, NULL, FALSE, NULL, NULL); |
541 if (ret == FAIL || (*arg = skip_arrow(*arg, equal_arrow)) == NULL) | 548 if (ret == FAIL |
549 || (*arg = skip_arrow(*arg, equal_arrow, &ret_type)) == NULL) | |
542 { | 550 { |
543 if (types_optional) | 551 if (types_optional) |
544 ga_clear_strings(&argtypes); | 552 ga_clear_strings(&argtypes); |
545 return NOTDONE; | 553 return NOTDONE; |
546 } | 554 } |
549 if (evaluate) | 557 if (evaluate) |
550 eval_lavars_used = &eval_lavars; | 558 eval_lavars_used = &eval_lavars; |
551 | 559 |
552 *arg = skipwhite_and_linebreak(*arg, evalarg); | 560 *arg = skipwhite_and_linebreak(*arg, evalarg); |
553 | 561 |
554 // Only recognize "{" as the start of a function body when followed by | 562 // Recognize "{" as the start of a function body. |
555 // white space, "{key: val}" is a dict. | 563 if (equal_arrow && **arg == '{') |
556 if (equal_arrow && **arg == '{' && IS_WHITE_OR_NUL((*arg)[1])) | |
557 { | 564 { |
558 // TODO: process the function body upto the "}". | 565 // TODO: process the function body upto the "}". |
566 // Return type is required then. | |
559 emsg("Lambda function body not supported yet"); | 567 emsg("Lambda function body not supported yet"); |
560 goto errret; | 568 goto errret; |
561 } | 569 } |
562 | 570 |
563 // Get the start and the end of the expression. | 571 // Get the start and the end of the expression. |
617 fp->uf_refcount = 1; | 625 fp->uf_refcount = 1; |
618 set_ufunc_name(fp, name); | 626 set_ufunc_name(fp, name); |
619 hash_add(&func_hashtab, UF2HIKEY(fp)); | 627 hash_add(&func_hashtab, UF2HIKEY(fp)); |
620 fp->uf_args = newargs; | 628 fp->uf_args = newargs; |
621 ga_init(&fp->uf_def_args); | 629 ga_init(&fp->uf_def_args); |
622 if (types_optional | 630 if (types_optional) |
623 && parse_argument_types(fp, &argtypes, FALSE) == FAIL) | 631 { |
624 goto errret; | 632 if (parse_argument_types(fp, &argtypes, FALSE) == FAIL) |
633 goto errret; | |
634 if (ret_type != NULL) | |
635 { | |
636 fp->uf_ret_type = parse_type(&ret_type, | |
637 &fp->uf_type_list, TRUE); | |
638 if (fp->uf_ret_type == NULL) | |
639 goto errret; | |
640 } | |
641 } | |
625 | 642 |
626 fp->uf_lines = newlines; | 643 fp->uf_lines = newlines; |
627 if (current_funccal != NULL && eval_lavars) | 644 if (current_funccal != NULL && eval_lavars) |
628 { | 645 { |
629 flags |= FC_CLOSURE; | 646 flags |= FC_CLOSURE; |
3750 if (ret_type == NULL) | 3767 if (ret_type == NULL) |
3751 fp->uf_ret_type = &t_void; | 3768 fp->uf_ret_type = &t_void; |
3752 else | 3769 else |
3753 { | 3770 { |
3754 p = ret_type; | 3771 p = ret_type; |
3755 fp->uf_ret_type = parse_type(&p, &fp->uf_type_list); | 3772 fp->uf_ret_type = parse_type(&p, &fp->uf_type_list, TRUE); |
3756 } | 3773 } |
3757 SOURCING_LNUM = lnum_save; | 3774 SOURCING_LNUM = lnum_save; |
3758 } | 3775 } |
3759 else | 3776 else |
3760 fp->uf_def_status = UF_NOT_COMPILED; | 3777 fp->uf_def_status = UF_NOT_COMPILED; |