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;