comparison src/userfunc.c @ 20397:c225be44692a v8.2.0753

patch 8.2.0753: Vim9: expressions are evaluated in the discovery phase Commit: https://github.com/vim/vim/commit/32e351179eacfc84f64cd5029e221582d400bb38 Author: Bram Moolenaar <Bram@vim.org> Date: Thu May 14 22:41:15 2020 +0200 patch 8.2.0753: Vim9: expressions are evaluated in the discovery phase Problem: Vim9: expressions are evaluated in the discovery phase. Solution: Bail out if an expression is not a constant. Require a type for declared constants.
author Bram Moolenaar <Bram@vim.org>
date Thu, 14 May 2020 22:45:04 +0200
parents 4c317d8c1051
children 5950284a517f
comparison
equal deleted inserted replaced
20396:89228c88b5c4 20397:c225be44692a
237 any_default = TRUE; 237 any_default = TRUE;
238 p = skipwhite(p) + 1; 238 p = skipwhite(p) + 1;
239 whitep = p; 239 whitep = p;
240 p = skipwhite(p); 240 p = skipwhite(p);
241 expr = p; 241 expr = p;
242 if (eval1(&p, &rettv, FALSE) != FAIL) 242 if (eval1(&p, &rettv, 0) != FAIL)
243 { 243 {
244 if (ga_grow(default_args, 1) == FAIL) 244 if (ga_grow(default_args, 1) == FAIL)
245 goto err_ret; 245 goto err_ret;
246 246
247 // trim trailing whitespace 247 // trim trailing whitespace
570 : funcexe->partial->pt_argc)) 570 : funcexe->partial->pt_argc))
571 { 571 {
572 argp = skipwhite(argp + 1); // skip the '(' or ',' 572 argp = skipwhite(argp + 1); // skip the '(' or ','
573 if (*argp == ')' || *argp == ',' || *argp == NUL) 573 if (*argp == ')' || *argp == ',' || *argp == NUL)
574 break; 574 break;
575 if (eval1(&argp, &argvars[argcount], funcexe->evaluate) == FAIL) 575 if (eval1(&argp, &argvars[argcount],
576 funcexe->evaluate ? EVAL_EVALUATE : 0) == FAIL)
576 { 577 {
577 ret = FAIL; 578 ret = FAIL;
578 break; 579 break;
579 } 580 }
580 ++argcount; 581 ++argcount;
1221 def_rettv.v_type = VAR_NUMBER; 1222 def_rettv.v_type = VAR_NUMBER;
1222 def_rettv.vval.v_number = -1; 1223 def_rettv.vval.v_number = -1;
1223 1224
1224 default_expr = ((char_u **)(fp->uf_def_args.ga_data)) 1225 default_expr = ((char_u **)(fp->uf_def_args.ga_data))
1225 [ai + fp->uf_def_args.ga_len]; 1226 [ai + fp->uf_def_args.ga_len];
1226 if (eval1(&default_expr, &def_rettv, TRUE) == FAIL) 1227 if (eval1(&default_expr, &def_rettv, EVAL_EVALUATE) == FAIL)
1227 { 1228 {
1228 default_arg_err = 1; 1229 default_arg_err = 1;
1229 break; 1230 break;
1230 } 1231 }
1231 } 1232 }
1366 char_u *p = *(char_u **)fp->uf_lines.ga_data + 7; 1367 char_u *p = *(char_u **)fp->uf_lines.ga_data + 7;
1367 1368
1368 // A Lambda always has the command "return {expr}". It is much faster 1369 // A Lambda always has the command "return {expr}". It is much faster
1369 // to evaluate {expr} directly. 1370 // to evaluate {expr} directly.
1370 ++ex_nesting_level; 1371 ++ex_nesting_level;
1371 (void)eval1(&p, rettv, TRUE); 1372 (void)eval1(&p, rettv, EVAL_EVALUATE);
1372 --ex_nesting_level; 1373 --ex_nesting_level;
1373 } 1374 }
1374 else 1375 else
1375 // call do_cmdline() to execute the lines 1376 // call do_cmdline() to execute the lines
1376 do_cmdline(NULL, get_func_line, (void *)fc, 1377 do_cmdline(NULL, get_func_line, (void *)fc,
3621 if (eap->skip) 3622 if (eap->skip)
3622 ++emsg_skip; 3623 ++emsg_skip;
3623 3624
3624 eap->nextcmd = NULL; 3625 eap->nextcmd = NULL;
3625 if ((*arg != NUL && *arg != '|' && *arg != '\n') 3626 if ((*arg != NUL && *arg != '|' && *arg != '\n')
3626 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 3627 && eval0(arg, &rettv, &eap->nextcmd, eap->skip ? 0 : EVAL_EVALUATE)
3628 != FAIL)
3627 { 3629 {
3628 if (!eap->skip) 3630 if (!eap->skip)
3629 returning = do_return(eap, FALSE, TRUE, &rettv); 3631 returning = do_return(eap, FALSE, TRUE, &rettv);
3630 else 3632 else
3631 clear_tv(&rettv); 3633 clear_tv(&rettv);
3678 { 3680 {
3679 // trans_function_name() doesn't work well when skipping, use eval0() 3681 // trans_function_name() doesn't work well when skipping, use eval0()
3680 // instead to skip to any following command, e.g. for: 3682 // instead to skip to any following command, e.g. for:
3681 // :if 0 | call dict.foo().bar() | endif 3683 // :if 0 | call dict.foo().bar() | endif
3682 ++emsg_skip; 3684 ++emsg_skip;
3683 if (eval0(eap->arg, &rettv, &eap->nextcmd, FALSE) != FAIL) 3685 if (eval0(eap->arg, &rettv, &eap->nextcmd, 0) != FAIL)
3684 clear_tv(&rettv); 3686 clear_tv(&rettv);
3685 --emsg_skip; 3687 --emsg_skip;
3686 return; 3688 return;
3687 } 3689 }
3688 3690
3766 } 3768 }
3767 if (has_watchexpr()) 3769 if (has_watchexpr())
3768 dbg_check_breakpoint(eap); 3770 dbg_check_breakpoint(eap);
3769 3771
3770 // Handle a function returning a Funcref, Dictionary or List. 3772 // Handle a function returning a Funcref, Dictionary or List.
3771 if (handle_subscript(&arg, &rettv, !eap->skip, TRUE, 3773 if (handle_subscript(&arg, &rettv, eap->skip ? 0 : EVAL_EVALUATE,
3772 name, &name) == FAIL) 3774 TRUE, name, &name) == FAIL)
3773 { 3775 {
3774 failed = TRUE; 3776 failed = TRUE;
3775 break; 3777 break;
3776 } 3778 }
3777 3779