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>
diff --git a/src/eval.c b/src/eval.c
index 46eec35..34502f9 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3515,7 +3515,8 @@
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 @@
return FAIL;
}
- evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
vim9script = in_vim9script();
if (getnext)
{
@@ -3553,20 +3553,20 @@
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
index 40b7809..d94ba4b 100644
--- a/src/testdir/test_expr.vim
+++ b/src/testdir/test_expr.vim
@@ -1041,6 +1041,50 @@
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
diff --git a/src/version.c b/src/version.c
index 111254e..33d4bf3 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2027,
+/**/
2026,
/**/
2025,