Mercurial > vim
diff src/userfunc.c @ 23318:c76240efdf02 v8.2.2204
patch 8.2.2204: Vim9: using -> both for method and lambda is confusing
Commit: https://github.com/vim/vim/commit/65c4415276394c871c7a8711c7633c19ec9235b1
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Dec 24 15:14:01 2020 +0100
patch 8.2.2204: Vim9: using -> both for method and lambda is confusing
Problem: Vim9: using -> both for method and lambda is confusing.
Solution: Use => for lambda in :def function.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 24 Dec 2020 15:15:05 +0100 |
parents | 112fa621b127 |
children | 1d11e3adbe52 |
line wrap: on
line diff
--- a/src/userfunc.c +++ b/src/userfunc.c @@ -154,6 +154,7 @@ one_function_arg( /* * Get function arguments. + * "argp" is advanced just after "endchar". */ int get_function_args( @@ -458,7 +459,31 @@ register_cfunc(cfunc_T cb, cfunc_free_T #endif /* + * Skip over "->" or "=>" after the arguments of a lambda. + * Return NULL if no valid arrow found. + */ + static char_u * +skip_arrow(char_u *start, int equal_arrow) +{ + char_u *s = start; + + if (equal_arrow) + { + if (*s == ':') + s = skip_type(skipwhite(s + 1), TRUE); + s = skipwhite(s); + if (*s != '=') + return NULL; + ++s; + } + if (*s != '>') + return NULL; + return skipwhite(s + 1); +} + +/* * Parse a lambda expression and get a Funcref from "*arg". + * "arg" points to the { in "{arg -> expr}" or the ( in "(arg) => expr" * When "types_optional" is TRUE optionally take argument types. * Return OK or FAIL. Returns NOTDONE for dict or {expr}. */ @@ -484,16 +509,20 @@ get_lambda_tv( int *old_eval_lavars = eval_lavars_used; int eval_lavars = FALSE; char_u *tofree = NULL; + int equal_arrow = **arg == '('; + + if (equal_arrow && !in_vim9script()) + return NOTDONE; ga_init(&newargs); ga_init(&newlines); - // First, check if this is a lambda expression. "->" must exist. + // First, check if this is a lambda expression. "->" or "=>" must exist. s = skipwhite(*arg + 1); - ret = get_function_args(&s, '-', NULL, + ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL, types_optional ? &argtypes : NULL, types_optional, NULL, NULL, TRUE, NULL, NULL); - if (ret == FAIL || *s != '>') + if (ret == FAIL || skip_arrow(s, equal_arrow) == NULL) return NOTDONE; // Parse the arguments again. @@ -502,18 +531,28 @@ get_lambda_tv( else pnewargs = NULL; *arg = skipwhite(*arg + 1); - ret = get_function_args(arg, '-', pnewargs, + ret = get_function_args(arg, equal_arrow ? ')' : '-', pnewargs, types_optional ? &argtypes : NULL, types_optional, &varargs, NULL, FALSE, NULL, NULL); - if (ret == FAIL || **arg != '>') - goto errret; + if (ret == FAIL || (*arg = skip_arrow(*arg, equal_arrow)) == NULL) + return NOTDONE; // Set up a flag for checking local variables and arguments. if (evaluate) eval_lavars_used = &eval_lavars; + *arg = skipwhite_and_linebreak(*arg, evalarg); + + // Only recognize "{" as the start of a function body when followed by + // white space, "{key: val}" is a dict. + if (equal_arrow && **arg == '{' && IS_WHITE_OR_NUL((*arg)[1])) + { + // TODO: process the function body upto the "}". + emsg("Lambda function body not supported yet"); + goto errret; + } + // Get the start and the end of the expression. - *arg = skipwhite_and_linebreak(*arg + 1, evalarg); start = *arg; ret = skip_expr_concatenate(arg, &start, &end, evalarg); if (ret == FAIL) @@ -525,13 +564,16 @@ get_lambda_tv( evalarg->eval_tofree = NULL; } - *arg = skipwhite_and_linebreak(*arg, evalarg); - if (**arg != '}') + if (!equal_arrow) { - semsg(_("E451: Expected }: %s"), *arg); - goto errret; + *arg = skipwhite_and_linebreak(*arg, evalarg); + if (**arg != '}') + { + semsg(_("E451: Expected }: %s"), *arg); + goto errret; + } + ++*arg; } - ++*arg; if (evaluate) {