# HG changeset patch # User Christian Brabandt # Date 1697356108 -7200 # Node ID fd8501e21b7d53746c2e654c6a408592271cfc7d # Parent fa3d813600d58debec39313e3701566397474599 patch 9.0.2027: Vim9: no support for bitwise operators in lambda funcs Commit: https://github.com/vim/vim/commit/de3295dd0c68a8d7540a751a99ee056fd5b9a7a4 Author: Yegappan Lakshmanan 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 Co-authored-by: Yegappan Lakshmanan diff --git a/src/eval.c b/src/eval.c --- 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; diff --git a/src/testdir/test_expr.vim b/src/testdir/test_expr.vim --- 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 => (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 => (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 => (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 => (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 diff --git a/src/version.c b/src/version.c --- 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,