summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-12-27 14:43:30 +0100
committerBram Moolenaar <Bram@vim.org>2020-12-27 14:43:30 +0100
commite462f52db3cab656485a71e4322b6cb18d564a06 (patch)
tree2bd955c07b2da6043ded912c39bb053a07f9e7e5
parent7e3ee7823ffc55b37e9718720263637ed7232646 (diff)
patch 8.2.2227: Vim9: recognizing lambda is too complicatedv8.2.2227
Problem: Vim9: recognizing lambda is too complicated. Solution: Call compile_lambda() and check for NOTDONE.
-rw-r--r--src/testdir/test_vim9_expr.vim18
-rw-r--r--src/userfunc.c2
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c62
4 files changed, 25 insertions, 59 deletions
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index e4f7f2d10d..9373db2045 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -1863,9 +1863,9 @@ def Test_expr7_lambda()
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(["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,13 +1964,9 @@ def Test_expr7_new_lambda()
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:')
+ 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,7 +2678,7 @@ func Test_expr7_fails()
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()"], 'E1004:', 1)
call CheckDefExecFailure(["{['a']: 1->len()"], 'E723:', 2)
endfunc
diff --git a/src/userfunc.c b/src/userfunc.c
index e496bce90a..2e93f3ee46 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -570,7 +570,7 @@ get_lambda_tv(
&varargs, NULL, FALSE, NULL, NULL);
if (ret == FAIL
|| (s = skip_arrow(*arg, equal_arrow, &ret_type,
- equal_arrow ? &white_error : NULL)) == NULL)
+ equal_arrow || in_vim9script() ? &white_error : NULL)) == NULL)
{
if (types_optional)
ga_clear_strings(&argtypes);
diff --git a/src/version.c b/src/version.c
index 989a7d9b0c..f9216ced87 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2227,
+/**/
2226,
/**/
2225,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index bd530b1e94..6a4e62730a 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -2949,10 +2949,12 @@ compile_list(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
/*
* 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,10 +2964,11 @@ compile_lambda(char_u **arg, cctx_T *cctx)
evalarg.eval_cctx = cctx;
// Get the funcref in "rettv".
- if (get_lambda_tv(arg, &rettv, TRUE, &evalarg) != OK)
+ r = get_lambda_tv(arg, &rettv, TRUE, &evalarg);
+ if (r != OK)
{
clear_evalarg(&evalarg, NULL);
- return FAIL;
+ return r;
}
// "rettv" will now be a partial referencing the function.
@@ -4001,26 +4004,13 @@ compile_expr7(
* 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);
- }
+ 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,32 +4041,10 @@ compile_expr7(
* 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;
- }
- }
+ 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;