changeset 21881:675bf9475fff v8.2.1490

patch 8.2.1490: Vim9: using /= with float and number doesn't work Commit: https://github.com/vim/vim/commit/93ad14710bdf77591f927a2b244bba6a8cbc7706 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Aug 19 22:02:41 2020 +0200 patch 8.2.1490: Vim9: using /= with float and number doesn't work Problem: Vim9: using /= with float and number doesn't work. Solution: Better support assignment with operator. (closes https://github.com/vim/vim/issues/6742)
author Bram Moolenaar <Bram@vim.org>
date Wed, 19 Aug 2020 22:15:04 +0200
parents 0520437529d0
children 80443e8b72ce
files src/testdir/test_vim9_script.vim src/version.c src/vim9compile.c
diffstat 3 files changed, 27 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -90,6 +90,18 @@ def Test_assignment()
   &ts %= 4
   assert_equal(2, &ts)
 
+  if has('float')
+    let f100: float = 100.0
+    f100 /= 5
+    assert_equal(20.0, f100)
+
+    let f200: float = 200.0
+    f200 /= 5.0
+    assert_equal(40.0, f200)
+
+    CheckDefFailure(['let nr: number = 200', 'nr /= 5.0'], 'E1012:')
+  endif
+
   lines =<< trim END
     vim9script
     &ts = 6
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1490,
+/**/
     1489,
 /**/
     1488,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -4923,10 +4923,11 @@ compile_assignment(char_u *arg, exarg_T 
 				lvar->lv_type = stacktype;
 			}
 		    }
-		    else
+		    else if (*op == '=')
 		    {
 			type_T *use_type = lvar->lv_type;
 
+			// without operator type is here, otherwise below
 			if (has_index)
 			{
 			    use_type = use_type->tt_member;
@@ -4934,7 +4935,7 @@ compile_assignment(char_u *arg, exarg_T 
 				use_type = &t_void;
 			}
 			if (need_type(stacktype, use_type, -1, cctx, FALSE)
-								   == FAIL)
+								       == FAIL)
 			    goto theend;
 		    }
 		}
@@ -5008,18 +5009,20 @@ compile_assignment(char_u *arg, exarg_T 
 
 	if (oplen > 0 && *op != '=')
 	{
-	    type_T	    *expected = &t_number;
+	    type_T	    *expected;
 	    type_T	    *stacktype;
 
-	    // TODO: if type is known use float or any operation
-	    // TODO: check operator matches variable type
-
 	    if (*op == '.')
 		expected = &t_string;
-	    else if (*op == '+')
+	    else
 		expected = member_type;
 	    stacktype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-	    if (need_type(stacktype, expected, -1, cctx, FALSE) == FAIL)
+	    if (
+#ifdef FEAT_FLOAT
+		// If variable is float operation with number is OK.
+		!(expected == &t_float && stacktype == &t_number) &&
+#endif
+		    need_type(stacktype, expected, -1, cctx, FALSE) == FAIL)
 		goto theend;
 
 	    if (*op == '.')
@@ -5034,20 +5037,8 @@ compile_assignment(char_u *arg, exarg_T 
 					       member_type, stacktype) == FAIL)
 		    goto theend;
 	    }
-	    else
-	    {
-		isn_T *isn = generate_instr_drop(cctx, ISN_OPNR, 1);
-
-		if (isn == NULL)
-		    goto theend;
-		switch (*op)
-		{
-		    case '-': isn->isn_arg.op.op_type = EXPR_SUB; break;
-		    case '*': isn->isn_arg.op.op_type = EXPR_MULT; break;
-		    case '/': isn->isn_arg.op.op_type = EXPR_DIV; break;
-		    case '%': isn->isn_arg.op.op_type = EXPR_REM; break;
-		}
-	    }
+	    else if (generate_two_op(cctx, op) == FAIL)
+		goto theend;
 	}
 
 	if (has_index)