summaryrefslogtreecommitdiff
path: root/src/vim9execute.c
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2022-05-22 19:13:49 +0100
committerBram Moolenaar <Bram@vim.org>2022-05-22 19:13:49 +0100
commita061f34191712df7dde7716705fe0ec074e9758e (patch)
treef8a3bf02c826aeb748d12bfa74ead3e9f74573a2 /src/vim9execute.c
parent9b2edfd3bf2f14a1faaee9b62930598a2e77a798 (diff)
downloadvim-git-a061f34191712df7dde7716705fe0ec074e9758e.tar.gz
patch 8.2.5003: cannot do bitwise shiftsv8.2.5003
Problem: Cannot do bitwise shifts. Solution: Add the >> and << operators. (Yegappan Lakshmanan, closes #8457)
Diffstat (limited to 'src/vim9execute.c')
-rw-r--r--src/vim9execute.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/vim9execute.c b/src/vim9execute.c
index b191dc998..b4fd9d591 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -4055,6 +4055,17 @@ exec_instructions(ectx_T *ectx)
varnumber_T res = 0;
int div_zero = FALSE;
+ if (iptr->isn_arg.op.op_type == EXPR_LSHIFT
+ || iptr->isn_arg.op.op_type == EXPR_RSHIFT)
+ {
+ if (arg2 < 0)
+ {
+ SOURCING_LNUM = iptr->isn_lnum;
+ emsg(_(e_bitshift_ops_must_be_postive));
+ goto on_error;
+ }
+ }
+
switch (iptr->isn_arg.op.op_type)
{
case EXPR_MULT: res = arg1 * arg2; break;
@@ -4077,6 +4088,21 @@ exec_instructions(ectx_T *ectx)
case EXPR_GEQUAL: res = arg1 >= arg2; break;
case EXPR_SMALLER: res = arg1 < arg2; break;
case EXPR_SEQUAL: res = arg1 <= arg2; break;
+ case EXPR_LSHIFT: if (arg2 > MAX_LSHIFT_BITS)
+ res = 0;
+ else
+ res = arg1 << arg2;
+ break;
+ case EXPR_RSHIFT: if (arg2 > MAX_LSHIFT_BITS)
+ res = 0;
+ else
+ {
+ res = arg1 >> arg2;
+ // clear the topmost sign bit
+ res &= ~((uvarnumber_T)1
+ << MAX_LSHIFT_BITS);
+ }
+ break;
default: break;
}
@@ -6016,6 +6042,8 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
case EXPR_REM: what = "%"; break;
case EXPR_SUB: what = "-"; break;
case EXPR_ADD: what = "+"; break;
+ case EXPR_LSHIFT: what = "<<"; break;
+ case EXPR_RSHIFT: what = ">>"; break;
default: what = "???"; break;
}
switch (iptr->isn_type)