Mercurial > vim
diff src/vim9compile.c @ 23352:37118deff718 v8.2.2219
patch 8.2.2219: Vim9: method call with expression not supported
Commit: https://github.com/vim/vim/commit/7e3682068bebc53a5d1e9eaaba61bb4fa9c612da
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Dec 25 21:56:57 2020 +0100
patch 8.2.2219: Vim9: method call with expression not supported
Problem: Vim9: method call with expression not supported.
Solution: Implement expr->(expr)().
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 25 Dec 2020 22:00:04 +0100 |
parents | 2060f53b7c17 |
children | eb7d8f39363c |
line wrap: on
line diff
--- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2817,9 +2817,8 @@ compile_call( && compile_load(&p, namebuf + varlen, cctx, FALSE, FALSE) == OK) { garray_T *stack = &cctx->ctx_type_stack; - type_T *type; - - type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; + type_T *type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; + res = generate_PCALL(cctx, argcount, namebuf, type, FALSE); goto theend; } @@ -3430,6 +3429,19 @@ get_compare_type(char_u *p, int *len, in } /* + * Skip over an expression, ignoring most errors. + */ + static void +skip_expr_cctx(char_u **arg, cctx_T *cctx) +{ + evalarg_T evalarg; + + CLEAR_FIELD(evalarg); + evalarg.eval_cctx = cctx; + skip_expr(arg, &evalarg); +} + +/* * Compile code to apply '-', '+' and '!'. * When "numeric_only" is TRUE do not apply '!'. */ @@ -3488,6 +3500,38 @@ compile_leader(cctx_T *cctx, int numeric } /* + * Compile "(expression)": recursive! + * Return FAIL/OK. + */ + static int +compile_parenthesis(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) +{ + int ret; + + *arg = skipwhite(*arg + 1); + if (ppconst->pp_used <= PPSIZE - 10) + { + ret = compile_expr1(arg, cctx, ppconst); + } + else + { + // Not enough space in ppconst, flush constants. + if (generate_ppconst(cctx, ppconst) == FAIL) + return FAIL; + ret = compile_expr0(arg, cctx); + } + *arg = skipwhite(*arg); + if (**arg == ')') + ++*arg; + else if (ret == OK) + { + emsg(_(e_missing_close)); + ret = FAIL; + } + return ret; +} + +/* * Compile whatever comes after "name" or "name()". * Advances "*arg" only when something was recognized. */ @@ -3572,10 +3616,42 @@ compile_subscript( } else if (**arg == '(') { - // Funcref call: list->(Refs[2])() - // or lambda: list->((arg) => expr)() - // TODO: make this work - if (compile_lambda_call(arg, cctx) == FAIL) + int argcount = 1; + char_u *expr; + garray_T *stack; + type_T *type; + + // Funcref call: list->(Refs[2])(arg) + // or lambda: list->((arg) => expr)(arg) + // Fist compile the arguments. + expr = *arg; + *arg = skipwhite(*arg + 1); + skip_expr_cctx(arg, cctx); + *arg = skipwhite(*arg); + if (**arg != ')') + { + semsg(_(e_missing_paren), *arg); + return FAIL; + } + ++*arg; + if (**arg != '(') + { + semsg(_(e_missing_paren), *arg); + return FAIL; + } + + *arg = skipwhite(*arg + 1); + if (compile_arguments(arg, cctx, &argcount) == FAIL) + return FAIL; + + // Compile the function expression. + if (compile_parenthesis(&expr, cctx, ppconst) == FAIL) + return FAIL; + + stack = &cctx->ctx_type_stack; + type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; + if (generate_PCALL(cctx, argcount, + (char_u *)"[expression]", type, FALSE) == FAIL) return FAIL; } else @@ -3998,28 +4074,7 @@ compile_expr7( break; } } - - // (expression): recursive! - *arg = skipwhite(*arg + 1); - if (ppconst->pp_used <= PPSIZE - 10) - { - ret = compile_expr1(arg, cctx, ppconst); - } - else - { - // Not enough space in ppconst, flush constants. - if (generate_ppconst(cctx, ppconst) == FAIL) - return FAIL; - ret = compile_expr0(arg, cctx); - } - *arg = skipwhite(*arg); - if (**arg == ')') - ++*arg; - else if (ret == OK) - { - emsg(_(e_missing_close)); - ret = FAIL; - } + ret = compile_parenthesis(arg, cctx, ppconst); } break; @@ -4597,7 +4652,7 @@ compile_expr2(char_u **arg, cctx_T *cctx * end: */ static int -compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) +compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) { char_u *p; int ppconst_used = ppconst->pp_used; @@ -4606,11 +4661,7 @@ compile_expr1(char_u **arg, cctx_T *cct // Ignore all kinds of errors when not producing code. if (cctx->ctx_skip == SKIP_YES) { - evalarg_T evalarg; - - CLEAR_FIELD(evalarg); - evalarg.eval_cctx = cctx; - skip_expr(arg, &evalarg); + skip_expr_cctx(arg, cctx); return OK; }