changeset 33564:fd8501e21b7d v9.0.2027

patch 9.0.2027: Vim9: no support for bitwise operators in lambda funcs Commit: https://github.com/vim/vim/commit/de3295dd0c68a8d7540a751a99ee056fd5b9a7a4 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Sun Oct 15 09:44:50 2023 +0200 patch 9.0.2027: Vim9: no support for bitwise operators in lambda funcs Problem: Vim9: no support for bitwise operators in lambda funcs Solution: move "evaluate" assignment a bit up in order to decide to perform bitwise operations closes: #13342 closes: #13345 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
author Christian Brabandt <cb@256bit.org>
date Sun, 15 Oct 2023 09:48:28 +0200
parents fa3d813600d5
children 6c04aed4cf31
files src/eval.c src/testdir/test_expr.vim src/version.c
diffstat 3 files changed, 60 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -3515,7 +3515,8 @@ eval5(char_u **arg, typval_T *rettv, eva
 	    return OK;
 
 	// Handle a bitwise left or right shift operator
-	if (rettv->v_type != VAR_NUMBER)
+	evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
+	if (evaluate && rettv->v_type != VAR_NUMBER)
 	{
 	    // left operand should be a number
 	    emsg(_(e_bitshift_ops_must_be_number));
@@ -3523,7 +3524,6 @@ eval5(char_u **arg, typval_T *rettv, eva
 	    return FAIL;
 	}
 
-	evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
 	vim9script = in_vim9script();
 	if (getnext)
 	{
@@ -3553,20 +3553,20 @@ eval5(char_u **arg, typval_T *rettv, eva
 	    return FAIL;
 	}
 
-	if (var2.v_type != VAR_NUMBER || var2.vval.v_number < 0)
-	{
-	    // right operand should be a positive number
-	    if (var2.v_type != VAR_NUMBER)
-		emsg(_(e_bitshift_ops_must_be_number));
-	    else
-		emsg(_(e_bitshift_ops_must_be_positive));
-	    clear_tv(rettv);
-	    clear_tv(&var2);
-	    return FAIL;
-	}
-
 	if (evaluate)
 	{
+	    if (var2.v_type != VAR_NUMBER || var2.vval.v_number < 0)
+	    {
+		// right operand should be a positive number
+		if (var2.v_type != VAR_NUMBER)
+		    emsg(_(e_bitshift_ops_must_be_number));
+		else
+		    emsg(_(e_bitshift_ops_must_be_positive));
+		clear_tv(rettv);
+		clear_tv(&var2);
+		return FAIL;
+	    }
+
 	    if (var2.vval.v_number > MAX_LSHIFT_BITS)
 		// shifting more bits than we have always results in zero
 		rettv->vval.v_number = 0;
--- a/src/testdir/test_expr.vim
+++ b/src/testdir/test_expr.vim
@@ -1041,6 +1041,50 @@ func Test_bitwise_shift()
      assert_equal(16, a)
   END
   call v9.CheckDefAndScriptSuccess(lines)
+
+  let lines =<< trim END
+    # Use in a lambda function
+    const DivBy2Ref_A = (n: number): number => n >> 1
+    assert_equal(16, DivBy2Ref_A(32))
+    const DivBy2Ref_B = (n: number): number => (<number>n) >> 1
+    assert_equal(16, DivBy2Ref_B(32))
+    const MultBy2Ref_A = (n: number): number => n << 1
+    assert_equal(8, MultBy2Ref_A(4))
+    const MultBy2Ref_B = (n: number): number => (<number>n) << 1
+    assert_equal(8, MultBy2Ref_B(4))
+
+    def DivBy2_A(): func(number): number
+      return (n: number): number => n >> 1
+    enddef
+    assert_equal(16, DivBy2_A()(32))
+    def DivBy2_B(): func(number): number
+      return (n: number): number => (<number>n) >> 1
+    enddef
+    assert_equal(16, DivBy2_B()(32))
+    def MultBy2_A(): func(number): number
+      return (n: number): number => n << 1
+    enddef
+    assert_equal(64, MultBy2_A()(32))
+    def MultBy2_B(): func(number): number
+      return (n: number): number => (<number>n) << 1
+    enddef
+    assert_equal(64, MultBy2_B()(32))
+  END
+  call v9.CheckDefAndScriptSuccess(lines)
+
+  " Use in a legacy lambda function
+  const DivBy2Ref_A = {n -> n >> 1}
+  call assert_equal(16, DivBy2Ref_A(32))
+  func DivBy2_A()
+    return {n -> n >> 1}
+  endfunc
+  call assert_equal(16, DivBy2_A()(32))
+  const MultBy2Ref_A = {n -> n << 1}
+  call assert_equal(64, MultBy2Ref_A(32))
+  func MultBy2_A()
+    return {n -> n << 1}
+  endfunc
+  call assert_equal(64, MultBy2_A()(32))
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2027,
+/**/
     2026,
 /**/
     2025,