@@ -2723,11 +2723,12 @@ compile_get_register(char_u **arg, cctx_T *cctx)
27232723
27242724/*
27252725 * Apply leading '!', '-' and '+' to constant "rettv".
2726+ * When "numeric_only" is TRUE do not apply '!'.
27262727 */
27272728 static int
2728- apply_leader (typval_T * rettv , char_u * start , char_u * end )
2729+ apply_leader (typval_T * rettv , int numeric_only , char_u * start , char_u * * end )
27292730{
2730- char_u * p = end ;
2731+ char_u * p = * end ;
27312732
27322733 // this works from end to start
27332734 while (p > start )
@@ -2762,6 +2763,11 @@ apply_leader(typval_T *rettv, char_u *start, char_u *end)
27622763 rettv -> vval .v_number = val ;
27632764 }
27642765 }
2766+ else if (numeric_only )
2767+ {
2768+ ++ p ;
2769+ break ;
2770+ }
27652771 else
27662772 {
27672773 int v = tv2bool (rettv );
@@ -2772,6 +2778,7 @@ apply_leader(typval_T *rettv, char_u *start, char_u *end)
27722778 rettv -> vval .v_number = v ? VVAL_FALSE : VVAL_TRUE ;
27732779 }
27742780 }
2781+ * end = p ;
27752782 return OK ;
27762783}
27772784
@@ -2860,11 +2867,12 @@ get_compare_type(char_u *p, int *len, int *type_is)
28602867
28612868/*
28622869 * Compile code to apply '-', '+' and '!'.
2870+ * When "numeric_only" is TRUE do not apply '!'.
28632871 */
28642872 static int
2865- compile_leader (cctx_T * cctx , char_u * start , char_u * end )
2873+ compile_leader (cctx_T * cctx , int numeric_only , char_u * start , char_u * * end )
28662874{
2867- char_u * p = end ;
2875+ char_u * p = * end ;
28682876
28692877 // this works from end to start
28702878 while (p > start )
@@ -2890,6 +2898,11 @@ compile_leader(cctx_T *cctx, char_u *start, char_u *end)
28902898 if (isn == NULL )
28912899 return FAIL ;
28922900 }
2901+ else if (numeric_only )
2902+ {
2903+ ++ p ;
2904+ break ;
2905+ }
28932906 else
28942907 {
28952908 int invert = TRUE;
@@ -2903,6 +2916,7 @@ compile_leader(cctx_T *cctx, char_u *start, char_u *end)
29032916 return FAIL ;
29042917 }
29052918 }
2919+ * end = p ;
29062920 return OK ;
29072921}
29082922
@@ -2914,10 +2928,12 @@ compile_leader(cctx_T *cctx, char_u *start, char_u *end)
29142928compile_subscript (
29152929 char_u * * arg ,
29162930 cctx_T * cctx ,
2917- char_u * * start_leader ,
2918- char_u * end_leader ,
2931+ char_u * start_leader ,
2932+ char_u * * end_leader ,
29192933 ppconst_T * ppconst )
29202934{
2935+ char_u * name_start = * end_leader ;
2936+
29212937 for (;;)
29222938 {
29232939 char_u * p = skipwhite (* arg );
@@ -2959,7 +2975,7 @@ compile_subscript(
29592975 * arg = skipwhite (p + 1 );
29602976 if (compile_arguments (arg , cctx , & argcount ) == FAIL )
29612977 return FAIL ;
2962- if (generate_PCALL (cctx , argcount , end_leader , type , TRUE) == FAIL )
2978+ if (generate_PCALL (cctx , argcount , name_start , type , TRUE) == FAIL )
29632979 return FAIL ;
29642980 }
29652981 else if (* p == '-' && p [1 ] == '>' )
@@ -2972,9 +2988,8 @@ compile_subscript(
29722988 // something->method()
29732989 // Apply the '!', '-' and '+' first:
29742990 // -1.0->func() works like (-1.0)->func()
2975- if (compile_leader (cctx , * start_leader , end_leader ) == FAIL )
2991+ if (compile_leader (cctx , TRUE, start_leader , end_leader ) == FAIL )
29762992 return FAIL ;
2977- * start_leader = end_leader ; // don't apply again later
29782993
29792994 p += 2 ;
29802995 * arg = skipwhite (p );
@@ -3329,13 +3344,12 @@ compile_expr7(
33293344
33303345 if (rettv -> v_type != VAR_UNKNOWN && used_before == ppconst -> pp_used )
33313346 {
3332- // apply the '!', ' -' and '+' before the constant
3333- if (apply_leader (rettv , start_leader , end_leader ) == FAIL )
3347+ // apply the '-' and '+' before the constant, but not '!'
3348+ if (apply_leader (rettv , TRUE, start_leader , & end_leader ) == FAIL )
33343349 {
33353350 clear_tv (rettv );
33363351 return FAIL ;
33373352 }
3338- start_leader = end_leader ; // don't apply again below
33393353
33403354 if (cctx -> ctx_skip == SKIP_YES )
33413355 clear_tv (rettv );
@@ -3373,18 +3387,18 @@ compile_expr7(
33733387
33743388 // Handle following "[]", ".member", etc.
33753389 // Then deal with prefixed '-', '+' and '!', if not done already.
3376- if (compile_subscript (arg , cctx , & start_leader , end_leader ,
3390+ if (compile_subscript (arg , cctx , start_leader , & end_leader ,
33773391 ppconst ) == FAIL )
33783392 return FAIL ;
33793393 if (ppconst -> pp_used > 0 )
33803394 {
33813395 // apply the '!', '-' and '+' before the constant
33823396 rettv = & ppconst -> pp_tv [ppconst -> pp_used - 1 ];
3383- if (apply_leader (rettv , start_leader , end_leader ) == FAIL )
3397+ if (apply_leader (rettv , FALSE, start_leader , & end_leader ) == FAIL )
33843398 return FAIL ;
33853399 return OK ;
33863400 }
3387- if (compile_leader (cctx , start_leader , end_leader ) == FAIL )
3401+ if (compile_leader (cctx , FALSE, start_leader , & end_leader ) == FAIL )
33883402 return FAIL ;
33893403 return OK ;
33903404}
0 commit comments