Skip to content

Commit a061f34

Browse files
yegappanbrammool
authored andcommitted
patch 8.2.5003: cannot do bitwise shifts
Problem: Cannot do bitwise shifts. Solution: Add the >> and << operators. (Yegappan Lakshmanan, closes #8457)
1 parent 9b2edfd commit a061f34

File tree

11 files changed

+554
-160
lines changed

11 files changed

+554
-160
lines changed

runtime/doc/eval.txt

Lines changed: 80 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -868,33 +868,36 @@ Expression syntax summary, from least to most significant:
868868
expr5 isnot expr5 different |List|, |Dictionary| or |Blob|
869869
instance
870870

871-
|expr5| expr6
872-
expr6 + expr6 ... number addition, list or blob concatenation
873-
expr6 - expr6 ... number subtraction
874-
expr6 . expr6 ... string concatenation
875-
expr6 .. expr6 ... string concatenation
871+
|expr5| expr6 << expr6 bitwise left shift
872+
expr6 >> expr6 bitwise right shift
876873

877874
|expr6| expr7
878-
expr7 * expr7 ... number multiplication
879-
expr7 / expr7 ... number division
880-
expr7 % expr7 ... number modulo
875+
expr7 + expr7 ... number addition, list or blob concatenation
876+
expr7 - expr7 ... number subtraction
877+
expr7 . expr7 ... string concatenation
878+
expr7 .. expr7 ... string concatenation
881879

882880
|expr7| expr8
883-
<type>expr8 type check and conversion (|Vim9| only)
881+
expr8 * expr8 ... number multiplication
882+
expr8 / expr8 ... number division
883+
expr8 % expr8 ... number modulo
884884

885885
|expr8| expr9
886-
! expr8 logical NOT
887-
- expr8 unary minus
888-
+ expr8 unary plus
886+
<type>expr9 type check and conversion (|Vim9| only)
889887

890888
|expr9| expr10
891-
expr9[expr1] byte of a String or item of a |List|
892-
expr9[expr1 : expr1] substring of a String or sublist of a |List|
893-
expr9.name entry in a |Dictionary|
894-
expr9(expr1, ...) function call with |Funcref| variable
895-
expr9->name(expr1, ...) |method| call
896-
897-
|expr10| number number constant
889+
! expr9 logical NOT
890+
- expr9 unary minus
891+
+ expr9 unary plus
892+
893+
|expr10| expr11
894+
expr10[expr1] byte of a String or item of a |List|
895+
expr10[expr1 : expr1] substring of a String or sublist of a |List|
896+
expr10.name entry in a |Dictionary|
897+
expr10(expr1, ...) function call with |Funcref| variable
898+
expr10->name(expr1, ...) |method| call
899+
900+
|expr11| number number constant
898901
"string" string constant, backslash is special
899902
'string' string constant, ' is doubled
900903
[expr1, ...] |List|
@@ -1128,14 +1131,26 @@ can be matched like an ordinary character. Examples:
11281131
"foo\nbar" =~ "\\n" evaluates to 0
11291132

11301133

1131-
expr5 and expr6 *expr5* *expr6* *E1036* *E1051*
1134+
expr5 *expr5* *bitwise-shift*
1135+
-----
1136+
expr6 << expr6 bitwise left shift *expr-<<*
1137+
expr6 >> expr6 bitwise right shift *expr->>*
1138+
*E1282* *E1283*
1139+
The "<<" and ">>" operators can be used to perform bitwise left or right shift
1140+
of the left operand by the number of bits specified by the right operand. The
1141+
operands must be positive numbers. The topmost bit (sign bit) is always
1142+
cleared for ">>". If the right operand (shift amount) is more than the
1143+
maximum number of bits in a number (|v:numbersize|) the result is zero.
1144+
1145+
1146+
expr6 and expr7 *expr6* *expr7* *E1036* *E1051*
11321147
---------------
1133-
expr6 + expr6 Number addition, |List| or |Blob| concatenation *expr-+*
1134-
expr6 - expr6 Number subtraction *expr--*
1135-
expr6 . expr6 String concatenation *expr-.*
1136-
expr6 .. expr6 String concatenation *expr-..*
1148+
expr7 + expr7 Number addition, |List| or |Blob| concatenation *expr-+*
1149+
expr7 - expr7 Number subtraction *expr--*
1150+
expr7 . expr7 String concatenation *expr-.*
1151+
expr7 .. expr7 String concatenation *expr-..*
11371152

1138-
For |Lists| only "+" is possible and then both expr6 must be a list. The
1153+
For |Lists| only "+" is possible and then both expr7 must be a list. The
11391154
result is a new list with the two lists Concatenated.
11401155

11411156
For String concatenation ".." is preferred, since "." is ambiguous, it is also
@@ -1147,9 +1162,9 @@ In |Vim9| script the arguments of ".." are converted to String for simple
11471162
types: Number, Float, Special and Bool. For other types |string()| should be
11481163
used.
11491164

1150-
expr7 * expr7 Number multiplication *expr-star*
1151-
expr7 / expr7 Number division *expr-/*
1152-
expr7 % expr7 Number modulo *expr-%*
1165+
expr8 * expr8 Number multiplication *expr-star*
1166+
expr8 / expr8 Number division *expr-/*
1167+
expr8 % expr8 Number modulo *expr-%*
11531168

11541169
In legacy script, for all operators except "." and "..", Strings are converted
11551170
to Numbers.
@@ -1191,18 +1206,18 @@ None of these work for |Funcref|s.
11911206
".", ".." and "%" do not work for Float. *E804* *E1035*
11921207

11931208

1194-
expr7 *expr7*
1209+
expr8 *expr8*
11951210
-----
1196-
<type>expr8
1211+
<type>expr9
11971212

11981213
This is only available in |Vim9| script, see |type-casting|.
11991214

12001215

1201-
expr8 *expr8*
1216+
expr9 *expr9*
12021217
-----
1203-
! expr8 logical NOT *expr-!*
1204-
- expr8 unary minus *expr-unary--*
1205-
+ expr8 unary plus *expr-unary-+*
1218+
! expr9 logical NOT *expr-!*
1219+
- expr9 unary minus *expr-unary--*
1220+
+ expr9 unary plus *expr-unary-+*
12061221

12071222
For '!' |TRUE| becomes |FALSE|, |FALSE| becomes |TRUE| (one).
12081223
For '-' the sign of the number is changed.
@@ -1224,30 +1239,30 @@ These three can be repeated and mixed. Examples:
12241239
--9 == 9
12251240

12261241

1227-
expr9 *expr9*
1228-
-----
1229-
This expression is either |expr10| or a sequence of the alternatives below,
1242+
expr10 *expr10*
1243+
------
1244+
This expression is either |expr11| or a sequence of the alternatives below,
12301245
in any order. E.g., these are all possible:
1231-
expr9[expr1].name
1232-
expr9.name[expr1]
1233-
expr9(expr1, ...)[expr1].name
1234-
expr9->(expr1, ...)[expr1]
1246+
expr10[expr1].name
1247+
expr10.name[expr1]
1248+
expr10(expr1, ...)[expr1].name
1249+
expr10->(expr1, ...)[expr1]
12351250
Evaluation is always from left to right.
12361251

1237-
expr9[expr1] item of String or |List| *expr-[]* *E111*
1252+
expr10[expr1] item of String or |List| *expr-[]* *E111*
12381253
*E909* *subscript* *E1062*
12391254
In legacy Vim script:
1240-
If expr9 is a Number or String this results in a String that contains the
1241-
expr1'th single byte from expr9. expr9 is used as a String (a number is
1255+
If expr10 is a Number or String this results in a String that contains the
1256+
expr1'th single byte from expr10. expr10 is used as a String (a number is
12421257
automatically converted to a String), expr1 as a Number. This doesn't
12431258
recognize multibyte encodings, see `byteidx()` for an alternative, or use
12441259
`split()` to turn the string into a list of characters. Example, to get the
12451260
byte under the cursor: >
12461261
:let c = getline(".")[col(".") - 1]
12471262
12481263
In |Vim9| script: *E1147* *E1148*
1249-
If expr9 is a String this results in a String that contains the expr1'th
1250-
single character (including any composing characters) from expr9. To use byte
1264+
If expr10 is a String this results in a String that contains the expr1'th
1265+
single character (including any composing characters) from expr10. To use byte
12511266
indexes use |strpart()|.
12521267

12531268
Index zero gives the first byte or character. Careful: text column numbers
@@ -1258,7 +1273,7 @@ String. A negative index always results in an empty string (reason: backward
12581273
compatibility). Use [-1:] to get the last byte or character.
12591274
In Vim9 script a negative index is used like with a list: count from the end.
12601275

1261-
If expr9 is a |List| then it results the item at index expr1. See |list-index|
1276+
If expr10 is a |List| then it results the item at index expr1. See |list-index|
12621277
for possible index values. If the index is out of range this results in an
12631278
error. Example: >
12641279
:let item = mylist[-1] " get last item
@@ -1268,14 +1283,14 @@ Generally, if a |List| index is equal to or higher than the length of the
12681283
error.
12691284

12701285

1271-
expr9[expr1a : expr1b] substring or sublist *expr-[:]*
1286+
expr10[expr1a : expr1b] substring or sublist *expr-[:]*
12721287

1273-
If expr9 is a String this results in the substring with the bytes or
1274-
characters from expr1a to and including expr1b. expr9 is used as a String,
1288+
If expr10 is a String this results in the substring with the bytes or
1289+
characters from expr1a to and including expr1b. expr10 is used as a String,
12751290
expr1a and expr1b are used as a Number.
12761291

12771292
In legacy Vim script the indexes are byte indexes. This doesn't recognize
1278-
multibyte encodings, see |byteidx()| for computing the indexes. If expr9 is
1293+
multibyte encodings, see |byteidx()| for computing the indexes. If expr10 is
12791294
a Number it is first converted to a String.
12801295

12811296
In Vim9 script the indexes are character indexes and include composing
@@ -1302,20 +1317,20 @@ Examples: >
13021317
:let s = s[:-3] " remove last two bytes
13031318
<
13041319
*slice*
1305-
If expr9 is a |List| this results in a new |List| with the items indicated by
1320+
If expr10 is a |List| this results in a new |List| with the items indicated by
13061321
the indexes expr1a and expr1b. This works like with a String, as explained
13071322
just above. Also see |sublist| below. Examples: >
13081323
:let l = mylist[:3] " first four items
13091324
:let l = mylist[4:4] " List with one item
13101325
:let l = mylist[:] " shallow copy of a List
13111326
1312-
If expr9 is a |Blob| this results in a new |Blob| with the bytes in the
1327+
If expr10 is a |Blob| this results in a new |Blob| with the bytes in the
13131328
indexes expr1a and expr1b, inclusive. Examples: >
13141329
:let b = 0zDEADBEEF
13151330
:let bs = b[1:2] " 0zADBE
13161331
:let bs = b[:] " copy of 0zDEADBEEF
13171332
1318-
Using expr9[expr1] or expr9[expr1a : expr1b] on a |Funcref| results in an
1333+
Using expr10[expr1] or expr10[expr1a : expr1b] on a |Funcref| results in an
13191334
error.
13201335

13211336
Watch out for confusion between a namespace and a variable followed by a colon
@@ -1324,11 +1339,11 @@ for a sublist: >
13241339
mylist[s:] " uses namespace s:, error!
13251340
13261341
1327-
expr9.name entry in a |Dictionary| *expr-entry*
1342+
expr10.name entry in a |Dictionary| *expr-entry*
13281343
*E1203* *E1229*
1329-
If expr9 is a |Dictionary| and it is followed by a dot, then the following
1344+
If expr10 is a |Dictionary| and it is followed by a dot, then the following
13301345
name will be used as a key in the |Dictionary|. This is just like:
1331-
expr9[name].
1346+
expr10[name].
13321347

13331348
The name must consist of alphanumeric characters, just like a variable name,
13341349
but it may start with a number. Curly braces cannot be used.
@@ -1345,17 +1360,17 @@ Note that the dot is also used for String concatenation. To avoid confusion
13451360
always put spaces around the dot for String concatenation.
13461361

13471362

1348-
expr9(expr1, ...) |Funcref| function call *E1085*
1363+
expr10(expr1, ...) |Funcref| function call *E1085*
13491364

1350-
When expr9 is a |Funcref| type variable, invoke the function it refers to.
1365+
When expr10 is a |Funcref| type variable, invoke the function it refers to.
13511366

13521367

1353-
expr9->name([args]) method call *method* *->*
1354-
expr9->{lambda}([args])
1368+
expr10->name([args]) method call *method* *->*
1369+
expr10->{lambda}([args])
13551370
*E260* *E276* *E1265*
13561371
For methods that are also available as global functions this is the same as: >
1357-
name(expr9 [, args])
1358-
There can also be methods specifically for the type of "expr9".
1372+
name(expr10 [, args])
1373+
There can also be methods specifically for the type of "expr10".
13591374

13601375
This allows for chaining, passing the value that one method returns to the
13611376
next method: >
@@ -1364,7 +1379,7 @@ next method: >
13641379
Example of using a lambda: >
13651380
GetPercentage()->{x -> x * 100}()->printf('%d%%')
13661381
<
1367-
When using -> the |expr8| operators will be applied first, thus: >
1382+
When using -> the |expr9| operators will be applied first, thus: >
13681383
-1.234->string()
13691384
Is equivalent to: >
13701385
(-1.234)->string()
@@ -1393,7 +1408,7 @@ When using the lambda form there must be no white space between the } and the
13931408
(.
13941409

13951410

1396-
*expr10*
1411+
*expr11*
13971412
number
13981413
------
13991414
number number constant *expr-number*

src/errors.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3279,3 +3279,9 @@ EXTERN char e_illegal_character_in_word[]
32793279
#endif
32803280
EXTERN char e_atom_engine_must_be_at_start_of_pattern[]
32813281
INIT(= N_("E1281: Atom '\\%%#=%c' must be at the start of the pattern"));
3282+
#ifdef FEAT_EVAL
3283+
EXTERN char e_bitshift_ops_must_be_number[]
3284+
INIT(= N_("E1282: bitshift operands must be numbers"));
3285+
EXTERN char e_bitshift_ops_must_be_postive[]
3286+
INIT(= N_("E1283: bitshift amount must be a positive number"));
3287+
#endif

0 commit comments

Comments
 (0)