0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 8.2.0723: Vim9: nested constant expression not evaluated compile time

Problem:    Vim9: nested constant expression not evaluated compile time.
Solution:   Use compile_expr1() for parenthesis.
This commit is contained in:
Bram Moolenaar
2020-05-09 18:28:34 +02:00
parent 7f14155f42
commit 1c74721233
3 changed files with 33 additions and 4 deletions

View File

@@ -1053,6 +1053,10 @@ def s:ComputeConst(): number
return 2 + 3 * 4 / 6 + 7 return 2 + 3 * 4 / 6 + 7
enddef enddef
def s:ComputeConstParen(): number
return ((2 + 4) * (8 / 2)) / (3 + 4)
enddef
def Test_simplify_const_expr() def Test_simplify_const_expr()
let res = execute('disass s:ConcatStrings') let res = execute('disass s:ConcatStrings')
assert_match('\<SNR>\d*_ConcatStrings.*' .. assert_match('\<SNR>\d*_ConcatStrings.*' ..
@@ -1065,6 +1069,12 @@ def Test_simplify_const_expr()
'\d PUSHNR 11.*' .. '\d PUSHNR 11.*' ..
'\d RETURN', '\d RETURN',
res) res)
res = execute('disass s:ComputeConstParen')
assert_match('\<SNR>\d*_ComputeConstParen.*' ..
'\d PUSHNR 3\>.*' ..
'\d RETURN',
res)
enddef enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker

View File

@@ -746,6 +746,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
723,
/**/ /**/
722, 722,
/**/ /**/

View File

@@ -136,7 +136,6 @@ struct cctx_S {
static char e_var_notfound[] = N_("E1001: variable not found: %s"); static char e_var_notfound[] = N_("E1001: variable not found: %s");
static char e_syntax_at[] = N_("E1002: Syntax error at %s"); static char e_syntax_at[] = N_("E1002: Syntax error at %s");
static int compile_expr0(char_u **arg, cctx_T *cctx);
static void delete_def_function_contents(dfunc_T *dfunc); static void delete_def_function_contents(dfunc_T *dfunc);
static void arg_type_mismatch(type_T *expected, type_T *actual, int argidx); static void arg_type_mismatch(type_T *expected, type_T *actual, int argidx);
static int check_type(type_T *expected, type_T *actual, int give_msg); static int check_type(type_T *expected, type_T *actual, int give_msg);
@@ -2358,11 +2357,16 @@ may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx)
// possible expressions on these constants are applied at compile time. If // possible expressions on these constants are applied at compile time. If
// that is not possible, the code to push the constants needs to be generated // that is not possible, the code to push the constants needs to be generated
// before other instructions. // before other instructions.
// Using 50 should be more than enough of 5 levels of ().
#define PPSIZE 50
typedef struct { typedef struct {
typval_T pp_tv[10]; // stack of ppconst constants typval_T pp_tv[PPSIZE]; // stack of ppconst constants
int pp_used; // active entries in pp_tv[] int pp_used; // active entries in pp_tv[]
} ppconst_T; } ppconst_T;
static int compile_expr0(char_u **arg, cctx_T *cctx);
static int compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst);
/* /*
* Generate a PUSH instruction for "tv". * Generate a PUSH instruction for "tv".
* "tv" will be consumed or cleared. * "tv" will be consumed or cleared.
@@ -3590,6 +3594,7 @@ compile_expr7(
char_u *start_leader, *end_leader; char_u *start_leader, *end_leader;
int ret = OK; int ret = OK;
typval_T *rettv = &ppconst->pp_tv[ppconst->pp_used]; typval_T *rettv = &ppconst->pp_tv[ppconst->pp_used];
int used_before = ppconst->pp_used;
/* /*
* Skip '!', '-' and '+' characters. They are handled later. * Skip '!', '-' and '+' characters. They are handled later.
@@ -3725,7 +3730,19 @@ compile_expr7(
* nested expression: (expression). * nested expression: (expression).
*/ */
case '(': *arg = skipwhite(*arg + 1); case '(': *arg = skipwhite(*arg + 1);
ret = compile_expr0(arg, cctx); // recursive!
// recursive!
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); *arg = skipwhite(*arg);
if (**arg == ')') if (**arg == ')')
++*arg; ++*arg;
@@ -3742,7 +3759,7 @@ compile_expr7(
if (ret == FAIL) if (ret == FAIL)
return FAIL; return FAIL;
if (rettv->v_type != VAR_UNKNOWN) if (rettv->v_type != VAR_UNKNOWN && used_before == ppconst->pp_used)
{ {
// apply the '!', '-' and '+' before the constant // apply the '!', '-' and '+' before the constant
if (apply_leader(rettv, start_leader, end_leader) == FAIL) if (apply_leader(rettv, start_leader, end_leader) == FAIL)