comparison 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
comparison
equal deleted inserted replaced
23351:ae0e6f75e315 23352:37118deff718
2815 p = namebuf; 2815 p = namebuf;
2816 if (STRNCMP(namebuf, "g:", 2) != 0 && !is_autoload 2816 if (STRNCMP(namebuf, "g:", 2) != 0 && !is_autoload
2817 && compile_load(&p, namebuf + varlen, cctx, FALSE, FALSE) == OK) 2817 && compile_load(&p, namebuf + varlen, cctx, FALSE, FALSE) == OK)
2818 { 2818 {
2819 garray_T *stack = &cctx->ctx_type_stack; 2819 garray_T *stack = &cctx->ctx_type_stack;
2820 type_T *type; 2820 type_T *type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
2821 2821
2822 type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
2823 res = generate_PCALL(cctx, argcount, namebuf, type, FALSE); 2822 res = generate_PCALL(cctx, argcount, namebuf, type, FALSE);
2824 goto theend; 2823 goto theend;
2825 } 2824 }
2826 2825
2827 // If we can find a global function by name generate the right call. 2826 // If we can find a global function by name generate the right call.
3428 } 3427 }
3429 return type; 3428 return type;
3430 } 3429 }
3431 3430
3432 /* 3431 /*
3432 * Skip over an expression, ignoring most errors.
3433 */
3434 static void
3435 skip_expr_cctx(char_u **arg, cctx_T *cctx)
3436 {
3437 evalarg_T evalarg;
3438
3439 CLEAR_FIELD(evalarg);
3440 evalarg.eval_cctx = cctx;
3441 skip_expr(arg, &evalarg);
3442 }
3443
3444 /*
3433 * Compile code to apply '-', '+' and '!'. 3445 * Compile code to apply '-', '+' and '!'.
3434 * When "numeric_only" is TRUE do not apply '!'. 3446 * When "numeric_only" is TRUE do not apply '!'.
3435 */ 3447 */
3436 static int 3448 static int
3437 compile_leader(cctx_T *cctx, int numeric_only, char_u *start, char_u **end) 3449 compile_leader(cctx_T *cctx, int numeric_only, char_u *start, char_u **end)
3486 *end = p; 3498 *end = p;
3487 return OK; 3499 return OK;
3488 } 3500 }
3489 3501
3490 /* 3502 /*
3503 * Compile "(expression)": recursive!
3504 * Return FAIL/OK.
3505 */
3506 static int
3507 compile_parenthesis(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
3508 {
3509 int ret;
3510
3511 *arg = skipwhite(*arg + 1);
3512 if (ppconst->pp_used <= PPSIZE - 10)
3513 {
3514 ret = compile_expr1(arg, cctx, ppconst);
3515 }
3516 else
3517 {
3518 // Not enough space in ppconst, flush constants.
3519 if (generate_ppconst(cctx, ppconst) == FAIL)
3520 return FAIL;
3521 ret = compile_expr0(arg, cctx);
3522 }
3523 *arg = skipwhite(*arg);
3524 if (**arg == ')')
3525 ++*arg;
3526 else if (ret == OK)
3527 {
3528 emsg(_(e_missing_close));
3529 ret = FAIL;
3530 }
3531 return ret;
3532 }
3533
3534 /*
3491 * Compile whatever comes after "name" or "name()". 3535 * Compile whatever comes after "name" or "name()".
3492 * Advances "*arg" only when something was recognized. 3536 * Advances "*arg" only when something was recognized.
3493 */ 3537 */
3494 static int 3538 static int
3495 compile_subscript( 3539 compile_subscript(
3570 if (compile_lambda_call(arg, cctx) == FAIL) 3614 if (compile_lambda_call(arg, cctx) == FAIL)
3571 return FAIL; 3615 return FAIL;
3572 } 3616 }
3573 else if (**arg == '(') 3617 else if (**arg == '(')
3574 { 3618 {
3575 // Funcref call: list->(Refs[2])() 3619 int argcount = 1;
3576 // or lambda: list->((arg) => expr)() 3620 char_u *expr;
3577 // TODO: make this work 3621 garray_T *stack;
3578 if (compile_lambda_call(arg, cctx) == FAIL) 3622 type_T *type;
3623
3624 // Funcref call: list->(Refs[2])(arg)
3625 // or lambda: list->((arg) => expr)(arg)
3626 // Fist compile the arguments.
3627 expr = *arg;
3628 *arg = skipwhite(*arg + 1);
3629 skip_expr_cctx(arg, cctx);
3630 *arg = skipwhite(*arg);
3631 if (**arg != ')')
3632 {
3633 semsg(_(e_missing_paren), *arg);
3634 return FAIL;
3635 }
3636 ++*arg;
3637 if (**arg != '(')
3638 {
3639 semsg(_(e_missing_paren), *arg);
3640 return FAIL;
3641 }
3642
3643 *arg = skipwhite(*arg + 1);
3644 if (compile_arguments(arg, cctx, &argcount) == FAIL)
3645 return FAIL;
3646
3647 // Compile the function expression.
3648 if (compile_parenthesis(&expr, cctx, ppconst) == FAIL)
3649 return FAIL;
3650
3651 stack = &cctx->ctx_type_stack;
3652 type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
3653 if (generate_PCALL(cctx, argcount,
3654 (char_u *)"[expression]", type, FALSE) == FAIL)
3579 return FAIL; 3655 return FAIL;
3580 } 3656 }
3581 else 3657 else
3582 { 3658 {
3583 // method call: list->method() 3659 // method call: list->method()
3996 { 4072 {
3997 ret = compile_lambda(arg, cctx); 4073 ret = compile_lambda(arg, cctx);
3998 break; 4074 break;
3999 } 4075 }
4000 } 4076 }
4001 4077 ret = compile_parenthesis(arg, cctx, ppconst);
4002 // (expression): recursive!
4003 *arg = skipwhite(*arg + 1);
4004 if (ppconst->pp_used <= PPSIZE - 10)
4005 {
4006 ret = compile_expr1(arg, cctx, ppconst);
4007 }
4008 else
4009 {
4010 // Not enough space in ppconst, flush constants.
4011 if (generate_ppconst(cctx, ppconst) == FAIL)
4012 return FAIL;
4013 ret = compile_expr0(arg, cctx);
4014 }
4015 *arg = skipwhite(*arg);
4016 if (**arg == ')')
4017 ++*arg;
4018 else if (ret == OK)
4019 {
4020 emsg(_(e_missing_close));
4021 ret = FAIL;
4022 }
4023 } 4078 }
4024 break; 4079 break;
4025 4080
4026 default: ret = NOTDONE; 4081 default: ret = NOTDONE;
4027 break; 4082 break;
4595 * JUMP_AND_KEEP_IF_TRUE end jump if true 4650 * JUMP_AND_KEEP_IF_TRUE end jump if true
4596 * EVAL expr1 4651 * EVAL expr1
4597 * end: 4652 * end:
4598 */ 4653 */
4599 static int 4654 static int
4600 compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) 4655 compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
4601 { 4656 {
4602 char_u *p; 4657 char_u *p;
4603 int ppconst_used = ppconst->pp_used; 4658 int ppconst_used = ppconst->pp_used;
4604 char_u *next; 4659 char_u *next;
4605 4660
4606 // Ignore all kinds of errors when not producing code. 4661 // Ignore all kinds of errors when not producing code.
4607 if (cctx->ctx_skip == SKIP_YES) 4662 if (cctx->ctx_skip == SKIP_YES)
4608 { 4663 {
4609 evalarg_T evalarg; 4664 skip_expr_cctx(arg, cctx);
4610
4611 CLEAR_FIELD(evalarg);
4612 evalarg.eval_cctx = cctx;
4613 skip_expr(arg, &evalarg);
4614 return OK; 4665 return OK;
4615 } 4666 }
4616 4667
4617 // Evaluate the first expression. 4668 // Evaluate the first expression.
4618 if (compile_expr2(arg, cctx, ppconst) == FAIL) 4669 if (compile_expr2(arg, cctx, ppconst) == FAIL)