Patch 8.2.2212
Problem:    Vim9: lambda with => does not work at the script level.
Solution:   Make it work.
Files:      src/eval.c, src/vim9type.c, src/userfunc.c,
            src/testdir/test_vim9_assign.vim, src/testdir/test_vim9_expr.vim


*** ../vim-8.2.2211/src/eval.c  2020-12-25 12:37:59.487073428 +0100
--- src/eval.c  2020-12-25 14:24:30.711248978 +0100
***************
*** 3349,3356 ****
  
      /*
       * nested expression: (expression).
       */
!     case '(': {
                    *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
                    ret = eval1(arg, rettv, evalarg);   // recursive!
  
--- 3349,3361 ----
  
      /*
       * nested expression: (expression).
+      * lambda: (arg) => expr
       */
!     case '(': ret = NOTDONE;
!               if (in_vim9script())
!                   ret = get_lambda_tv(arg, rettv, TRUE, evalarg);
!               if (ret == NOTDONE)
!               {
                    *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
                    ret = eval1(arg, rettv, evalarg);   // recursive!
  
*** ../vim-8.2.2211/src/vim9type.c      2020-12-25 13:20:36.795341032 +0100
--- src/vim9type.c      2020-12-25 14:49:31.862464312 +0100
***************
*** 338,343 ****
--- 338,345 ----
            if (ufunc->uf_def_status == UF_TO_BE_COMPILED
                            && compile_def_function(ufunc, TRUE, NULL) == FAIL)
                return NULL;
+           if (ufunc->uf_func_type == NULL)
+               set_function_type(ufunc);
            if (ufunc->uf_func_type != NULL)
                return ufunc->uf_func_type;
        }
*** ../vim-8.2.2211/src/userfunc.c      2020-12-25 12:37:59.487073428 +0100
--- src/userfunc.c      2020-12-25 15:15:45.784583299 +0100
***************
*** 461,481 ****
  /*
   * Skip over "->" or "=>" after the arguments of a lambda.
   * If ": type" is found make "ret_type" point to "type".
   * Return NULL if no valid arrow found.
   */
      static char_u *
! skip_arrow(char_u *start, int equal_arrow, char_u **ret_type)
  {
!     char_u *s = start;
  
      if (equal_arrow)
      {
        if (*s == ':')
        {
            s = skipwhite(s + 1);
            *ret_type = s;
            s = skip_type(s, TRUE);
        }
        s = skipwhite(s);
        if (*s != '=')
            return NULL;
--- 461,495 ----
  /*
   * Skip over "->" or "=>" after the arguments of a lambda.
   * If ": type" is found make "ret_type" point to "type".
+  * If "white_error" is not NULL check for correct use of white space and set
+  * "white_error" to TRUE if there is an error.
   * Return NULL if no valid arrow found.
   */
      static char_u *
! skip_arrow(
!       char_u  *start,
!       int     equal_arrow,
!       char_u  **ret_type,
!       int     *white_error)
  {
!     char_u  *s = start;
!     char_u  *bef = start - 2; // "start" points to > of ->
  
      if (equal_arrow)
      {
        if (*s == ':')
        {
+           if (white_error != NULL && !VIM_ISWHITE(s[1]))
+           {
+               *white_error = TRUE;
+               semsg(_(e_white_space_required_after_str), ":");
+               return NULL;
+           }
            s = skipwhite(s + 1);
            *ret_type = s;
            s = skip_type(s, TRUE);
        }
+       bef = s;
        s = skipwhite(s);
        if (*s != '=')
            return NULL;
***************
*** 483,488 ****
--- 497,510 ----
      }
      if (*s != '>')
        return NULL;
+     if (white_error != NULL && ((!VIM_ISWHITE(*bef) && *bef != '{')
+               || !IS_WHITE_OR_NUL(s[1])))
+     {
+       *white_error = TRUE;
+       semsg(_(e_white_space_required_before_and_after_str),
+                                                   equal_arrow ? "=>" : "->");
+       return NULL;
+     }
      return skipwhite(s + 1);
  }
  
***************
*** 516,521 ****
--- 538,544 ----
      int               eval_lavars = FALSE;
      char_u    *tofree = NULL;
      int               equal_arrow = **arg == '(';
+     int               white_error = FALSE;
  
      if (equal_arrow && !in_vim9script())
        return NOTDONE;
***************
*** 529,535 ****
      ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL,
            types_optional ? &argtypes : NULL, types_optional,
                                                 NULL, NULL, TRUE, NULL, NULL);
!     if (ret == FAIL || skip_arrow(s, equal_arrow, &ret_type) == NULL)
      {
        if (types_optional)
            ga_clear_strings(&argtypes);
--- 552,558 ----
      ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL,
            types_optional ? &argtypes : NULL, types_optional,
                                                 NULL, NULL, TRUE, NULL, NULL);
!     if (ret == FAIL || skip_arrow(s, equal_arrow, &ret_type, NULL) == NULL)
      {
        if (types_optional)
            ga_clear_strings(&argtypes);
***************
*** 546,557 ****
            types_optional ? &argtypes : NULL, types_optional,
                                            &varargs, NULL, FALSE, NULL, NULL);
      if (ret == FAIL
!                 || (*arg = skip_arrow(*arg, equal_arrow, &ret_type)) == NULL)
      {
        if (types_optional)
            ga_clear_strings(&argtypes);
!       return NOTDONE;
      }
  
      // Set up a flag for checking local variables and arguments.
      if (evaluate)
--- 569,582 ----
            types_optional ? &argtypes : NULL, types_optional,
                                            &varargs, NULL, FALSE, NULL, NULL);
      if (ret == FAIL
!                 || (s = skip_arrow(*arg, equal_arrow, &ret_type,
!                                                       &white_error)) == NULL)
      {
        if (types_optional)
            ga_clear_strings(&argtypes);
!       return white_error ? FAIL : NOTDONE;
      }
+     *arg = s;
  
      // Set up a flag for checking local variables and arguments.
      if (evaluate)
***************
*** 647,654 ****
            if (register_closure(fp) == FAIL)
                goto errret;
        }
-       else
-           fp->uf_scoped = NULL;
  
  #ifdef FEAT_PROFILE
        if (prof_def_func())
--- 672,677 ----
*** ../vim-8.2.2211/src/testdir/test_vim9_assign.vim    2020-12-22 
21:19:35.293652280 +0100
--- src/testdir/test_vim9_assign.vim    2020-12-25 15:17:37.444205938 +0100
***************
*** 1027,1037 ****
    # check if assign a lambda to a variable which type is func or any.
    var lines =<< trim END
        vim9script
!       var FuncRef = {->123}
        assert_equal(123, FuncRef())
!       var FuncRef_Func: func = {->123}
        assert_equal(123, FuncRef_Func())
!       var FuncRef_Any: any = {->123}
        assert_equal(123, FuncRef_Any())
    END
    CheckScriptSuccess(lines)
--- 1027,1037 ----
    # check if assign a lambda to a variable which type is func or any.
    var lines =<< trim END
        vim9script
!       var FuncRef = {-> 123}
        assert_equal(123, FuncRef())
!       var FuncRef_Func: func = {-> 123}
        assert_equal(123, FuncRef_Func())
!       var FuncRef_Any: any = {-> 123}
        assert_equal(123, FuncRef_Any())
    END
    CheckScriptSuccess(lines)
*** ../vim-8.2.2211/src/testdir/test_vim9_expr.vim      2020-12-25 
12:37:59.487073428 +0100
--- src/testdir/test_vim9_expr.vim      2020-12-25 15:20:16.947668968 +0100
***************
*** 1953,1967 ****
        # Lambda returning a dict
        var Lmb = () => ({key: 42})
        assert_equal({key: 42}, Lmb())
    END
!   CheckDefSuccess(lines)
  
    CheckDefFailure(["var Ref = (a)=>a + 1"], 'E1001:')
    CheckDefFailure(["var Ref = (a)=> a + 1"], 'E1001:')
    CheckDefFailure(["var Ref = (a) =>a + 1"], 'E1001:')
  
!   CheckDefSuccess(["var Ref: func(number): string = (a: number): string => 
'x'"])
!   CheckDefSuccess(["var Ref: func(number): any = (a: number): any => 'x'"])
    CheckDefFailure(["var Ref: func(number): number = (a: number): string => 
'x'"], 'E1012:')
    CheckDefFailure(["var Ref: func(number): string = (a: number): string => 
99"], 'E1012:')
  
--- 1953,1977 ----
        # Lambda returning a dict
        var Lmb = () => ({key: 42})
        assert_equal({key: 42}, Lmb())
+ 
+       var RefOne: func(number): string = (a: number): string => 'x'
+       var RefTwo: func(number): any = (a: number): any => 'x'
+ 
+       var Fx = (a) => ({k1: 0,
+                          k2: 1})
+       var Fy = (a) => [0,
+                        1]
    END
!   CheckDefAndScriptSuccess(lines)
  
    CheckDefFailure(["var Ref = (a)=>a + 1"], 'E1001:')
    CheckDefFailure(["var Ref = (a)=> a + 1"], 'E1001:')
    CheckDefFailure(["var Ref = (a) =>a + 1"], 'E1001:')
  
!   CheckScriptFailure(["vim9script", "var Ref = (a)=>a + 1"], 'E1004:')
!   CheckScriptFailure(["vim9script", "var Ref = (a)=> a + 1"], 'E1004:')
!   CheckScriptFailure(["vim9script", "var Ref = (a) =>a + 1"], 'E1004:')
! 
    CheckDefFailure(["var Ref: func(number): number = (a: number): string => 
'x'"], 'E1012:')
    CheckDefFailure(["var Ref: func(number): string = (a: number): string => 
99"], 'E1012:')
  
***************
*** 1978,1988 ****
  #        'E1106: 2 arguments too many')
  #  CheckDefFailure(["echo 'asdf'->{a -> a}(x)"], 'E1001:', 1)
  
-   CheckDefSuccess(['var Fx = (a) => ({k1: 0,', ' k2: 1})'])
    CheckDefFailure(['var Fx = (a) => ({k1: 0', ' k2: 1})'], 'E722:', 2)
    CheckDefFailure(['var Fx = (a) => ({k1: 0,', ' k2 1})'], 'E720:', 2)
  
-   CheckDefSuccess(['var Fx = (a) => [0,', ' 1]'])
    CheckDefFailure(['var Fx = (a) => [0', ' 1]'], 'E696:', 2)
  enddef
  
--- 1988,1996 ----
*** ../vim-8.2.2211/src/version.c       2020-12-25 13:52:33.537313154 +0100
--- src/version.c       2020-12-25 14:20:32.736003818 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2212,
  /**/

-- 
How To Keep A Healthy Level Of Insanity:
4. Put your garbage can on your desk and label it "in".

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202012251425.0BPEP48n3543913%40masaka.moolenaar.net.

Raspunde prin e-mail lui