@@ -1197,6 +1197,9 @@ eval_foldexpr(char_u *arg, int *cp)
11971197 * ":let var = expr" assignment command.
11981198 * ":let var += expr" assignment command.
11991199 * ":let var -= expr" assignment command.
1200+ * ":let var *= expr" assignment command.
1201+ * ":let var /= expr" assignment command.
1202+ * ":let var %= expr" assignment command.
12001203 * ":let var .= expr" assignment command.
12011204 * ":let [var1, var2] = expr" unpack list.
12021205 */
@@ -1216,10 +1219,10 @@ ex_let(exarg_T *eap)
12161219 argend = skip_var_list (arg , & var_count , & semicolon );
12171220 if (argend == NULL )
12181221 return ;
1219- if (argend > arg && argend [-1 ] == '.' ) /* for var.='str' */
1222+ if (argend > arg && argend [-1 ] == '.' ) // for var.='str'
12201223 -- argend ;
12211224 expr = skipwhite (argend );
1222- if (* expr != '=' && !(vim_strchr ((char_u * )"+-." , * expr ) != NULL
1225+ if (* expr != '=' && !(vim_strchr ((char_u * )"+-*/% ." , * expr ) != NULL
12231226 && expr [1 ] == '=' ))
12241227 {
12251228 /*
@@ -1249,8 +1252,8 @@ ex_let(exarg_T *eap)
12491252 op [1 ] = NUL ;
12501253 if (* expr != '=' )
12511254 {
1252- if (vim_strchr ((char_u * )"+-." , * expr ) != NULL )
1253- op [0 ] = * expr ; /* +=, -= or .= */
1255+ if (vim_strchr ((char_u * )"+-*/% ." , * expr ) != NULL )
1256+ op [0 ] = * expr ; // +=, -=, *=, /=, %= or .=
12541257 expr = skipwhite (expr + 2 );
12551258 }
12561259 else
@@ -1671,7 +1674,7 @@ ex_let_one(
16711674 semsg (_ (e_invarg2 ), name - 1 );
16721675 else
16731676 {
1674- if (op != NULL && ( * op == '+' || * op == '-' ) )
1677+ if (op != NULL && vim_strchr (( char_u * ) "+-*/%" , * op ) != NULL )
16751678 semsg (_ (e_letwrong ), op );
16761679 else if (endchars != NULL
16771680 && vim_strchr (endchars , * skipwhite (arg )) == NULL )
@@ -1744,18 +1747,22 @@ ex_let_one(
17441747 || (opt_type == 0 && * op != '.' ))
17451748 {
17461749 semsg (_ (e_letwrong ), op );
1747- s = NULL ; /* don't set the value */
1750+ s = NULL ; // don't set the value
17481751 }
17491752 else
17501753 {
1751- if (opt_type == 1 ) /* number */
1754+ if (opt_type == 1 ) // number
17521755 {
1753- if (* op == '+' )
1754- n = numval + n ;
1755- else
1756- n = numval - n ;
1756+ switch (* op )
1757+ {
1758+ case '+' : n = numval + n ; break ;
1759+ case '-' : n = numval - n ; break ;
1760+ case '*' : n = numval * n ; break ;
1761+ case '/' : n = numval / n ; break ;
1762+ case '%' : n = numval % n ; break ;
1763+ }
17571764 }
1758- else if (opt_type == 0 && stringval != NULL ) /* string */
1765+ else if (opt_type == 0 && stringval != NULL ) // string
17591766 {
17601767 s = concat_str (stringval , s );
17611768 vim_free (stringval );
@@ -1779,7 +1786,7 @@ ex_let_one(
17791786 else if (* arg == '@' )
17801787 {
17811788 ++ arg ;
1782- if (op != NULL && ( * op == '+' || * op == '-' ) )
1789+ if (op != NULL && vim_strchr (( char_u * ) "+-*/%" , * op ) != NULL )
17831790 semsg (_ (e_letwrong ), op );
17841791 else if (endchars != NULL
17851792 && vim_strchr (endchars , * skipwhite (arg + 1 )) == NULL )
@@ -2254,7 +2261,8 @@ clear_lval(lval_T *lp)
22542261/*
22552262 * Set a variable that was parsed by get_lval() to "rettv".
22562263 * "endp" points to just after the parsed name.
2257- * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=".
2264+ * "op" is NULL, "+" for "+=", "-" for "-=", "*" for "*=", "/" for "/=",
2265+ * "%" for "%=", "." for ".=" or "=" for "=".
22582266 */
22592267 static void
22602268set_var_lval (
@@ -2327,7 +2335,7 @@ set_var_lval(
23272335 {
23282336 typval_T tv ;
23292337
2330- /* handle +=, -= and .= */
2338+ // handle +=, -=, *=, /=, %= and .=
23312339 di = NULL ;
23322340 if (get_var_tv (lp -> ll_name , (int )STRLEN (lp -> ll_name ),
23332341 & tv , & di , TRUE, FALSE) == OK )
@@ -2448,7 +2456,8 @@ set_var_lval(
24482456}
24492457
24502458/*
2451- * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2"
2459+ * Handle "tv1 += tv2", "tv1 -= tv2", "tv1 *= tv2", "tv1 /= tv2", "tv1 %= tv2"
2460+ * and "tv1 .= tv2"
24522461 * Returns OK or FAIL.
24532462 */
24542463 static int
@@ -2490,7 +2499,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
24902499 case VAR_LIST :
24912500 if (* op != '+' || tv2 -> v_type != VAR_LIST )
24922501 break ;
2493- /* List += List */
2502+ // List += List
24942503 if (tv1 -> vval .v_list != NULL && tv2 -> vval .v_list != NULL )
24952504 list_extend (tv1 -> vval .v_list , tv2 -> vval .v_list , NULL );
24962505 return OK ;
@@ -2499,30 +2508,39 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
24992508 case VAR_STRING :
25002509 if (tv2 -> v_type == VAR_LIST )
25012510 break ;
2502- if (* op == '+' || * op == '-' )
2511+ if (vim_strchr (( char_u * ) "+-*/%" , * op ) != NULL )
25032512 {
2504- /* nr += nr or nr -= nr*/
2513+ // nr += nr , nr -= nr , nr *=nr , nr /= nr , nr %= nr
25052514 n = tv_get_number (tv1 );
25062515#ifdef FEAT_FLOAT
25072516 if (tv2 -> v_type == VAR_FLOAT )
25082517 {
25092518 float_T f = n ;
25102519
2511- if (* op == '+' )
2512- f += tv2 -> vval .v_float ;
2513- else
2514- f -= tv2 -> vval .v_float ;
2520+ if (* op == '%' )
2521+ break ;
2522+ switch (* op )
2523+ {
2524+ case '+' : f += tv2 -> vval .v_float ; break ;
2525+ case '-' : f -= tv2 -> vval .v_float ; break ;
2526+ case '*' : f *= tv2 -> vval .v_float ; break ;
2527+ case '/' : f /= tv2 -> vval .v_float ; break ;
2528+ }
25152529 clear_tv (tv1 );
25162530 tv1 -> v_type = VAR_FLOAT ;
25172531 tv1 -> vval .v_float = f ;
25182532 }
25192533 else
25202534#endif
25212535 {
2522- if (* op == '+' )
2523- n += tv_get_number (tv2 );
2524- else
2525- n -= tv_get_number (tv2 );
2536+ switch (* op )
2537+ {
2538+ case '+' : n += tv_get_number (tv2 ); break ;
2539+ case '-' : n -= tv_get_number (tv2 ); break ;
2540+ case '*' : n *= tv_get_number (tv2 ); break ;
2541+ case '/' : n /= tv_get_number (tv2 ); break ;
2542+ case '%' : n %= tv_get_number (tv2 ); break ;
2543+ }
25262544 clear_tv (tv1 );
25272545 tv1 -> v_type = VAR_NUMBER ;
25282546 tv1 -> vval .v_number = n ;
@@ -2533,7 +2551,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
25332551 if (tv2 -> v_type == VAR_FLOAT )
25342552 break ;
25352553
2536- /* str .= str */
2554+ // str .= str
25372555 s = tv_get_string (tv1 );
25382556 s = concat_str (s , tv_get_string_buf (tv2 , numbuf ));
25392557 clear_tv (tv1 );
@@ -2547,18 +2565,22 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
25472565 {
25482566 float_T f ;
25492567
2550- if (* op == '.' || (tv2 -> v_type != VAR_FLOAT
2568+ if (* op == '%' || * op == '.'
2569+ || (tv2 -> v_type != VAR_FLOAT
25512570 && tv2 -> v_type != VAR_NUMBER
25522571 && tv2 -> v_type != VAR_STRING ))
25532572 break ;
25542573 if (tv2 -> v_type == VAR_FLOAT )
25552574 f = tv2 -> vval .v_float ;
25562575 else
25572576 f = tv_get_number (tv2 );
2558- if (* op == '+' )
2559- tv1 -> vval .v_float += f ;
2560- else
2561- tv1 -> vval .v_float -= f ;
2577+ switch (* op )
2578+ {
2579+ case '+' : tv1 -> vval .v_float += f ; break ;
2580+ case '-' : tv1 -> vval .v_float -= f ; break ;
2581+ case '*' : tv1 -> vval .v_float *= f ; break ;
2582+ case '/' : tv1 -> vval .v_float /= f ; break ;
2583+ }
25622584 }
25632585#endif
25642586 return OK ;
0 commit comments