]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.2027: Vim9: no support for bitwise operators in lambda funcs v9.0.2027
authorYegappan Lakshmanan <yegappan@yahoo.com>
Sun, 15 Oct 2023 07:44:50 +0000 (09:44 +0200)
committerChristian Brabandt <cb@256bit.org>
Sun, 15 Oct 2023 07:44:50 +0000 (09:44 +0200)
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>
src/eval.c
src/testdir/test_expr.vim
src/version.c

index 46eec355722f538de6fc3c9183d7ecb1400f1502..34502f965b3f88d4f9121a2ebec255c839d03da7 100644 (file)
@@ -3515,7 +3515,8 @@ eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
            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, evalarg_T *evalarg)
            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, evalarg_T *evalarg)
            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;
index 40b7809d1536144d7409ec3e3c797347720b0dbe..d94ba4b58c26dea284292022bde25ac3d9bdb07a 100644 (file)
@@ -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
index 111254eade1f2f41eedfc69c766fc88de87da14d..33d4bf3ef6ada7b60eb42b41835b515511a183e1 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2027,
 /**/
     2026,
 /**/