To: vim_dev@googlegroups.com Subject: Patch 8.2.2212 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@Moolenaar.net -- 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 ///