forked from aniani/vim
patch 8.2.2219: Vim9: method call with expression not supported
Problem: Vim9: method call with expression not supported. Solution: Implement expr->(expr)().
This commit is contained in:
@@ -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_T *type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
||||
|
||||
type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
||||
res = generate_PCALL(cctx, argcount, namebuf, type, FALSE);
|
||||
goto theend;
|
||||
}
|
||||
@@ -3429,6 +3428,19 @@ get_compare_type(char_u *p, int *len, int *type_is)
|
||||
return type;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 '!'.
|
||||
@@ -3487,6 +3499,38 @@ compile_leader(cctx_T *cctx, int numeric_only, char_u *start, char_u **end)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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, ppconst_T *ppconst)
|
||||
* 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 *cctx, ppconst_T *ppconst)
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user