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:
@@ -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
|
||||||
|
@@ -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,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -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)
|
||||||
|
Reference in New Issue
Block a user