Patch 8.2.2227
Problem: Vim9: recognizing lambda is too complicated.
Solution: Call compile_lambda() and check for NOTDONE.
Files: src/vim9compile.c, src/userfunc.c, src/testdir/test_vim9_expr.vim
*** ../vim-8.2.2226/src/vim9compile.c 2020-12-27 13:39:44.659044653 +0100
--- src/vim9compile.c 2020-12-27 14:35:03.267064104 +0100
***************
*** 2949,2958 ****
--- 2949,2960 ----
/*
* parse a lambda: "{arg, arg -> expr}" or "(arg, arg) => expr"
* "*arg" points to the '{'.
+ * Returns OK/FAIL when a lambda is recognized, NOTDONE if it's not a lambda.
*/
static int
compile_lambda(char_u **arg, cctx_T *cctx)
{
+ int r;
typval_T rettv;
ufunc_T *ufunc;
evalarg_T evalarg;
***************
*** 2962,2971 ****
evalarg.eval_cctx = cctx;
// Get the funcref in "rettv".
! if (get_lambda_tv(arg, &rettv, TRUE, &evalarg) != OK)
{
clear_evalarg(&evalarg, NULL);
! return FAIL;
}
// "rettv" will now be a partial referencing the function.
--- 2964,2974 ----
evalarg.eval_cctx = cctx;
// Get the funcref in "rettv".
! r = get_lambda_tv(arg, &rettv, TRUE, &evalarg);
! if (r != OK)
{
clear_evalarg(&evalarg, NULL);
! return r;
}
// "rettv" will now be a partial referencing the function.
***************
*** 4001,4026 ****
* Lambda: {arg, arg -> expr}
* Dictionary: {'key': val, 'key': val}
*/
! case '{': {
! char_u *start = skipwhite(*arg + 1);
! char_u *after = start;
! garray_T ga_arg;
!
! // Find out what comes after the arguments.
! ret = get_function_args(&after, '-', NULL,
! &ga_arg, TRUE, NULL, NULL,
! TRUE, NULL, NULL);
! if (ret != FAIL && after[0] == '>'
! && ((after > start + 2
! && VIM_ISWHITE(after[-2]))
! || after == start + 1)
! && IS_WHITE_OR_NUL(after[1]))
! // TODO: if we go with the "(arg) => expr" syntax
! // remove this
! ret = compile_lambda(arg, cctx);
! else
! ret = compile_dict(arg, cctx, ppconst);
! }
break;
/*
--- 4004,4016 ----
* Lambda: {arg, arg -> expr}
* Dictionary: {'key': val, 'key': val}
*/
! case '{': // Try parsing as a lambda, if NOTDONE is returned it
! // must be a dict.
! // TODO: if we go with the "(arg) => expr" syntax remove
! // this
! ret = compile_lambda(arg, cctx);
! if (ret == NOTDONE)
! ret = compile_dict(arg, cctx, ppconst);
break;
/*
***************
*** 4051,4082 ****
* lambda: (arg, arg) => expr
* funcref: (arg, arg) => { statement }
*/
! case '(': {
! char_u *start = skipwhite(*arg + 1);
! char_u *after = start;
! garray_T ga_arg;
!
! // Find out if "=>" comes after the ().
! ret = get_function_args(&after, ')', NULL,
! &ga_arg, TRUE, NULL, NULL,
! TRUE, NULL, NULL);
! if (ret == OK && VIM_ISWHITE(
! *after == ':' ? after[1] : *after))
! {
! if (*after == ':')
! // Skip over type in "(arg): type".
! after = skip_type(skipwhite(after + 1), TRUE);
!
! after = skipwhite(after);
! if (after[0] == '=' && after[1] == '>'
! && IS_WHITE_OR_NUL(after[2]))
! {
! ret = compile_lambda(arg, cctx);
! break;
! }
! }
ret = compile_parenthesis(arg, cctx, ppconst);
- }
break;
default: ret = NOTDONE;
--- 4041,4050 ----
* lambda: (arg, arg) => expr
* funcref: (arg, arg) => { statement }
*/
! case '(': // if compile_lambda returns NOTDONE then it must be (expr)
! ret = compile_lambda(arg, cctx);
! if (ret == NOTDONE)
ret = compile_parenthesis(arg, cctx, ppconst);
break;
default: ret = NOTDONE;
*** ../vim-8.2.2226/src/userfunc.c 2020-12-26 17:43:03.284516767 +0100
--- src/userfunc.c 2020-12-27 14:30:51.651986714 +0100
***************
*** 570,576 ****
&varargs, NULL, FALSE, NULL, NULL);
if (ret == FAIL
|| (s = skip_arrow(*arg, equal_arrow, &ret_type,
! equal_arrow ? &white_error : NULL)) == NULL)
{
if (types_optional)
ga_clear_strings(&argtypes);
--- 570,576 ----
&varargs, NULL, FALSE, NULL, NULL);
if (ret == FAIL
|| (s = skip_arrow(*arg, equal_arrow, &ret_type,
! equal_arrow || in_vim9script() ? &white_error : NULL)) == NULL)
{
if (types_optional)
ga_clear_strings(&argtypes);
*** ../vim-8.2.2226/src/testdir/test_vim9_expr.vim 2020-12-25 21:56:53.412944936 +0100
--- src/testdir/test_vim9_expr.vim 2020-12-27 14:36:02.906845507 +0100
***************
*** 1863,1871 ****
END
CheckDefAndScriptSuccess(lines)
! CheckDefFailure(["var Ref = {a->a + 1}"], 'E720:')
! CheckDefFailure(["var Ref = {a-> a + 1}"], 'E720:')
! CheckDefFailure(["var Ref = {a ->a + 1}"], 'E720:')
CheckDefFailure(["filter([1, 2], {k,v -> 1})"], 'E1069:', 1)
# error is in first line of the lambda
--- 1863,1871 ----
END
CheckDefAndScriptSuccess(lines)
! CheckDefFailure(["var Ref = {a->a + 1}"], 'E1004:')
! CheckDefFailure(["var Ref = {a-> a + 1}"], 'E1004:')
! CheckDefFailure(["var Ref = {a ->a + 1}"], 'E1004:')
CheckDefFailure(["filter([1, 2], {k,v -> 1})"], 'E1069:', 1)
# error is in first line of the lambda
***************
*** 1964,1976 ****
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:')
--- 1964,1972 ----
END
CheckDefAndScriptSuccess(lines)
! CheckDefAndScriptFailure(["var Ref = (a)=>a + 1"], 'E1004:')
! CheckDefAndScriptFailure(["var Ref = (a)=> a + 1"], 'E1004:')
! CheckDefAndScriptFailure(["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:')
***************
*** 2682,2688 ****
call CheckDefFailure(["'yes'->", "Echo()"], 'E488: Trailing characters: ->', 1)
call CheckDefExecFailure(["[1, 2->len()"], 'E697:', 2)
! call CheckDefExecFailure(["{a: 1->len()"], 'E723:', 2)
call CheckDefExecFailure(["{['a']: 1->len()"], 'E723:', 2)
endfunc
--- 2678,2684 ----
call CheckDefFailure(["'yes'->", "Echo()"], 'E488: Trailing characters: ->', 1)
call CheckDefExecFailure(["[1, 2->len()"], 'E697:', 2)
! call CheckDefExecFailure(["{a: 1->len()"], 'E1004:', 1)
call CheckDefExecFailure(["{['a']: 1->len()"], 'E723:', 2)
endfunc
*** ../vim-8.2.2226/src/version.c 2020-12-27 14:02:23.818275527 +0100
--- src/version.c 2020-12-27 14:36:34.074731272 +0100
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 2227,
/**/
--
The only backup you need is the one that you didn't have time for.
(Murphy)
/// Bram Moolenaar -- Br...@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 ///