Skip to content

Commit 4495d39

Browse files
authored
Merge pull request #203 from mattn/shift-op
support lshift, rshift
2 parents 9766ea9 + edff9c9 commit 4495d39

File tree

6 files changed

+173
-13
lines changed

6 files changed

+173
-13
lines changed

autoload/vimlparser.vim

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ let s:NODE_EVAL = 95
143143
let s:NODE_HEREDOC = 96
144144
let s:NODE_METHOD = 97
145145
let s:NODE_ECHOCONSOLE = 98
146+
let s:NODE_LSHIFT = 99
147+
let s:NODE_RSHIFT = 100
146148

147149
let s:TOKEN_EOF = 1
148150
let s:TOKEN_EOL = 2
@@ -213,6 +215,8 @@ let s:TOKEN_BLOB = 66
213215
let s:TOKEN_LITCOPEN = 67
214216
let s:TOKEN_DOTDOT = 68
215217
let s:TOKEN_HEREDOC = 69
218+
let s:TOKEN_LSHIFT = 70
219+
let s:TOKEN_RSHIFT = 71
216220

217221
let s:MAX_FUNC_ARGS = 20
218222

@@ -3525,6 +3529,9 @@ function! s:ExprTokenizer.get2() abort
35253529
elseif r.p(1) ==# '#'
35263530
call r.seek_cur(2)
35273531
return self.token(s:TOKEN_GTCS, '>#', pos)
3532+
elseif r.p(1) ==# '>'
3533+
call r.seek_cur(2)
3534+
return self.token(s:TOKEN_RSHIFT, '>>', pos)
35283535
else
35293536
call r.seek_cur(1)
35303537
return self.token(s:TOKEN_GT, '>', pos)
@@ -3536,6 +3543,9 @@ function! s:ExprTokenizer.get2() abort
35363543
elseif r.p(1) ==# '#'
35373544
call r.seek_cur(2)
35383545
return self.token(s:TOKEN_LTCS, '<#', pos)
3546+
elseif r.p(1) ==# '<'
3547+
call r.seek_cur(2)
3548+
return self.token(s:TOKEN_LSHIFT, '<<', pos)
35393549
else
35403550
call r.seek_cur(1)
35413551
return self.token(s:TOKEN_LT, '<', pos)
@@ -4021,32 +4031,59 @@ endfunction
40214031
" expr6 . expr6 ..
40224032
" expr6 .. expr6 ..
40234033
function! s:ExprParser.parse_expr5() abort
4024-
let left = self.parse_expr6()
4034+
let left = self.parse_expr5_5()
40254035
while s:TRUE
40264036
let pos = self.reader.tell()
40274037
let token = self.tokenizer.get()
40284038
if token.type ==# s:TOKEN_PLUS
40294039
let node = s:Node(s:NODE_ADD)
40304040
let node.pos = token.pos
40314041
let node.left = left
4032-
let node.right = self.parse_expr6()
4042+
let node.right = self.parse_expr5_5()
40334043
let left = node
40344044
elseif token.type ==# s:TOKEN_MINUS
40354045
let node = s:Node(s:NODE_SUBTRACT)
40364046
let node.pos = token.pos
40374047
let node.left = left
4038-
let node.right = self.parse_expr6()
4048+
let node.right = self.parse_expr5_5()
40394049
let left = node
40404050
elseif token.type ==# s:TOKEN_DOTDOT " TODO check scriptversion?
40414051
let node = s:Node(s:NODE_CONCAT)
40424052
let node.pos = token.pos
40434053
let node.left = left
4044-
let node.right = self.parse_expr6()
4054+
let node.right = self.parse_expr5_5()
40454055
let left = node
40464056
elseif token.type ==# s:TOKEN_DOT " TODO check scriptversion?
40474057
let node = s:Node(s:NODE_CONCAT)
40484058
let node.pos = token.pos
40494059
let node.left = left
4060+
let node.right = self.parse_expr5_5()
4061+
let left = node
4062+
else
4063+
call self.reader.seek_set(pos)
4064+
break
4065+
endif
4066+
endwhile
4067+
return left
4068+
endfunction
4069+
4070+
" expr5_5: expr6 << expr6 ..
4071+
" expr6 >> expr6 ..
4072+
function! s:ExprParser.parse_expr5_5() abort
4073+
let left = self.parse_expr6()
4074+
while s:TRUE
4075+
let pos = self.reader.tell()
4076+
let token = self.tokenizer.get()
4077+
if token.type ==# s:TOKEN_LSHIFT
4078+
let node = s:Node(s:NODE_LSHIFT)
4079+
let node.pos = token.pos
4080+
let node.left = left
4081+
let node.right = self.parse_expr6()
4082+
let left = node
4083+
elseif token.type ==# s:TOKEN_RSHIFT
4084+
let node = s:Node(s:NODE_RSHIFT)
4085+
let node.pos = token.pos
4086+
let node.left = left
40504087
let node.right = self.parse_expr6()
40514088
let left = node
40524089
else
@@ -5151,6 +5188,10 @@ function! s:Compiler.compile(node) abort
51515188
return self.compile_divide(a:node)
51525189
elseif a:node.type ==# s:NODE_REMAINDER
51535190
return self.compile_remainder(a:node)
5191+
elseif a:node.type ==# s:NODE_LSHIFT
5192+
return self.compile_lshift(a:node)
5193+
elseif a:node.type ==# s:NODE_RSHIFT
5194+
return self.compile_rshift(a:node)
51545195
elseif a:node.type ==# s:NODE_NOT
51555196
return self.compile_not(a:node)
51565197
elseif a:node.type ==# s:NODE_PLUS
@@ -5600,6 +5641,14 @@ function! s:Compiler.compile_remainder(node) abort
56005641
return printf('(%% %s %s)', self.compile(a:node.left), self.compile(a:node.right))
56015642
endfunction
56025643

5644+
function! s:Compiler.compile_lshift(node) abort
5645+
return printf('(<< %s %s)', self.compile(a:node.left), self.compile(a:node.right))
5646+
endfunction
5647+
5648+
function! s:Compiler.compile_rshift(node) abort
5649+
return printf('(>> %s %s)', self.compile(a:node.left), self.compile(a:node.right))
5650+
endfunction
5651+
56035652
function! s:Compiler.compile_not(node) abort
56045653
return printf('(! %s)', self.compile(a:node.left))
56055654
endfunction

js/vimlparser.js

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,8 @@ var NODE_EVAL = 95;
324324
var NODE_HEREDOC = 96;
325325
var NODE_METHOD = 97;
326326
var NODE_ECHOCONSOLE = 98;
327+
var NODE_LSHIFT = 99;
328+
var NODE_RSHIFT = 100;
327329
var TOKEN_EOF = 1;
328330
var TOKEN_EOL = 2;
329331
var TOKEN_SPACE = 3;
@@ -393,6 +395,8 @@ var TOKEN_BLOB = 66;
393395
var TOKEN_LITCOPEN = 67;
394396
var TOKEN_DOTDOT = 68;
395397
var TOKEN_HEREDOC = 69;
398+
var TOKEN_LSHIFT = 70;
399+
var TOKEN_RSHIFT = 71;
396400
var MAX_FUNC_ARGS = 20;
397401
function isalpha(c) {
398402
return viml_eqregh(c, "^[A-Za-z]$");
@@ -2709,6 +2713,10 @@ ExprTokenizer.prototype.get2 = function() {
27092713
r.seek_cur(2);
27102714
return this.token(TOKEN_GTCS, ">#", pos);
27112715
}
2716+
else if (r.p(1) == ">") {
2717+
r.seek_cur(2);
2718+
return this.token(TOKEN_RSHIFT, ">>", pos);
2719+
}
27122720
else {
27132721
r.seek_cur(1);
27142722
return this.token(TOKEN_GT, ">", pos);
@@ -2723,6 +2731,10 @@ ExprTokenizer.prototype.get2 = function() {
27232731
r.seek_cur(2);
27242732
return this.token(TOKEN_LTCS, "<#", pos);
27252733
}
2734+
else if (r.p(1) == "<") {
2735+
r.seek_cur(2);
2736+
return this.token(TOKEN_LSHIFT, "<<", pos);
2737+
}
27262738
else {
27272739
r.seek_cur(1);
27282740
return this.token(TOKEN_LT, "<", pos);
@@ -3274,37 +3286,66 @@ ExprParser.prototype.parse_expr4 = function() {
32743286
// expr6 . expr6 ..
32753287
// expr6 .. expr6 ..
32763288
ExprParser.prototype.parse_expr5 = function() {
3277-
var left = this.parse_expr6();
3289+
var left = this.parse_expr5_5();
32783290
while (TRUE) {
32793291
var pos = this.reader.tell();
32803292
var token = this.tokenizer.get();
32813293
if (token.type == TOKEN_PLUS) {
32823294
var node = Node(NODE_ADD);
32833295
node.pos = token.pos;
32843296
node.left = left;
3285-
node.right = this.parse_expr6();
3297+
node.right = this.parse_expr5_5();
32863298
var left = node;
32873299
}
32883300
else if (token.type == TOKEN_MINUS) {
32893301
var node = Node(NODE_SUBTRACT);
32903302
node.pos = token.pos;
32913303
node.left = left;
3292-
node.right = this.parse_expr6();
3304+
node.right = this.parse_expr5_5();
32933305
var left = node;
32943306
}
32953307
else if (token.type == TOKEN_DOTDOT) {
32963308
// TODO check scriptversion?
32973309
var node = Node(NODE_CONCAT);
32983310
node.pos = token.pos;
32993311
node.left = left;
3300-
node.right = this.parse_expr6();
3312+
node.right = this.parse_expr5_5();
33013313
var left = node;
33023314
}
33033315
else if (token.type == TOKEN_DOT) {
33043316
// TODO check scriptversion?
33053317
var node = Node(NODE_CONCAT);
33063318
node.pos = token.pos;
33073319
node.left = left;
3320+
node.right = this.parse_expr5_5();
3321+
var left = node;
3322+
}
3323+
else {
3324+
this.reader.seek_set(pos);
3325+
break;
3326+
}
3327+
}
3328+
return left;
3329+
}
3330+
3331+
// expr5_5: expr6 << expr6 ..
3332+
// expr6 >> expr6 ..
3333+
ExprParser.prototype.parse_expr5_5 = function() {
3334+
var left = this.parse_expr6();
3335+
while (TRUE) {
3336+
var pos = this.reader.tell();
3337+
var token = this.tokenizer.get();
3338+
if (token.type == TOKEN_LSHIFT) {
3339+
var node = Node(NODE_LSHIFT);
3340+
node.pos = token.pos;
3341+
node.left = left;
3342+
node.right = this.parse_expr6();
3343+
var left = node;
3344+
}
3345+
else if (token.type == TOKEN_RSHIFT) {
3346+
var node = Node(NODE_RSHIFT);
3347+
node.pos = token.pos;
3348+
node.left = left;
33083349
node.right = this.parse_expr6();
33093350
var left = node;
33103351
}
@@ -4536,6 +4577,12 @@ Compiler.prototype.compile = function(node) {
45364577
else if (node.type == NODE_REMAINDER) {
45374578
return this.compile_remainder(node);
45384579
}
4580+
else if (node.type == NODE_LSHIFT) {
4581+
return this.compile_lshift(node);
4582+
}
4583+
else if (node.type == NODE_RSHIFT) {
4584+
return this.compile_rshift(node);
4585+
}
45394586
else if (node.type == NODE_NOT) {
45404587
return this.compile_not(node);
45414588
}
@@ -5023,6 +5070,14 @@ Compiler.prototype.compile_remainder = function(node) {
50235070
return viml_printf("(%% %s %s)", this.compile(node.left), this.compile(node.right));
50245071
}
50255072

5073+
Compiler.prototype.compile_lshift = function(node) {
5074+
return viml_printf("(<< %s %s)", this.compile(node.left), this.compile(node.right));
5075+
}
5076+
5077+
Compiler.prototype.compile_rshift = function(node) {
5078+
return viml_printf("(>> %s %s)", this.compile(node.left), this.compile(node.right));
5079+
}
5080+
50265081
Compiler.prototype.compile_not = function(node) {
50275082
return viml_printf("(! %s)", this.compile(node.left));
50285083
}

py/vimlparser.py

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ def viml_stridx(a, b):
311311
NODE_HEREDOC = 96
312312
NODE_METHOD = 97
313313
NODE_ECHOCONSOLE = 98
314+
NODE_LSHIFT = 99
315+
NODE_RSHIFT = 100
314316
TOKEN_EOF = 1
315317
TOKEN_EOL = 2
316318
TOKEN_SPACE = 3
@@ -380,6 +382,8 @@ def viml_stridx(a, b):
380382
TOKEN_LITCOPEN = 67
381383
TOKEN_DOTDOT = 68
382384
TOKEN_HEREDOC = 69
385+
TOKEN_LSHIFT = 70
386+
TOKEN_RSHIFT = 71
383387
MAX_FUNC_ARGS = 20
384388

385389

@@ -2209,6 +2213,9 @@ def get2(self):
22092213
elif r.p(1) == "#":
22102214
r.seek_cur(2)
22112215
return self.token(TOKEN_GTCS, ">#", pos)
2216+
elif r.p(1) == ">":
2217+
r.seek_cur(2)
2218+
return self.token(TOKEN_RSHIFT, ">>", pos)
22122219
else:
22132220
r.seek_cur(1)
22142221
return self.token(TOKEN_GT, ">", pos)
@@ -2219,6 +2226,9 @@ def get2(self):
22192226
elif r.p(1) == "#":
22202227
r.seek_cur(2)
22212228
return self.token(TOKEN_LTCS, "<#", pos)
2229+
elif r.p(1) == "<":
2230+
r.seek_cur(2)
2231+
return self.token(TOKEN_LSHIFT, "<<", pos)
22222232
else:
22232233
r.seek_cur(1)
22242234
return self.token(TOKEN_LT, "<", pos)
@@ -2666,34 +2676,58 @@ def parse_expr4(self):
26662676
# expr6 . expr6 ..
26672677
# expr6 .. expr6 ..
26682678
def parse_expr5(self):
2669-
left = self.parse_expr6()
2679+
left = self.parse_expr5_5()
26702680
while TRUE:
26712681
pos = self.reader.tell()
26722682
token = self.tokenizer.get()
26732683
if token.type == TOKEN_PLUS:
26742684
node = Node(NODE_ADD)
26752685
node.pos = token.pos
26762686
node.left = left
2677-
node.right = self.parse_expr6()
2687+
node.right = self.parse_expr5_5()
26782688
left = node
26792689
elif token.type == TOKEN_MINUS:
26802690
node = Node(NODE_SUBTRACT)
26812691
node.pos = token.pos
26822692
node.left = left
2683-
node.right = self.parse_expr6()
2693+
node.right = self.parse_expr5_5()
26842694
left = node
26852695
elif token.type == TOKEN_DOTDOT:
26862696
# TODO check scriptversion?
26872697
node = Node(NODE_CONCAT)
26882698
node.pos = token.pos
26892699
node.left = left
2690-
node.right = self.parse_expr6()
2700+
node.right = self.parse_expr5_5()
26912701
left = node
26922702
elif token.type == TOKEN_DOT:
26932703
# TODO check scriptversion?
26942704
node = Node(NODE_CONCAT)
26952705
node.pos = token.pos
26962706
node.left = left
2707+
node.right = self.parse_expr5_5()
2708+
left = node
2709+
else:
2710+
self.reader.seek_set(pos)
2711+
break
2712+
return left
2713+
2714+
# expr5_5: expr6 << expr6 ..
2715+
# expr6 >> expr6 ..
2716+
def parse_expr5_5(self):
2717+
left = self.parse_expr6()
2718+
while TRUE:
2719+
pos = self.reader.tell()
2720+
token = self.tokenizer.get()
2721+
if token.type == TOKEN_LSHIFT:
2722+
node = Node(NODE_LSHIFT)
2723+
node.pos = token.pos
2724+
node.left = left
2725+
node.right = self.parse_expr6()
2726+
left = node
2727+
elif token.type == TOKEN_RSHIFT:
2728+
node = Node(NODE_RSHIFT)
2729+
node.pos = token.pos
2730+
node.left = left
26972731
node.right = self.parse_expr6()
26982732
left = node
26992733
else:
@@ -3647,6 +3681,10 @@ def compile(self, node):
36473681
return self.compile_divide(node)
36483682
elif node.type == NODE_REMAINDER:
36493683
return self.compile_remainder(node)
3684+
elif node.type == NODE_LSHIFT:
3685+
return self.compile_lshift(node)
3686+
elif node.type == NODE_RSHIFT:
3687+
return self.compile_rshift(node)
36503688
elif node.type == NODE_NOT:
36513689
return self.compile_not(node)
36523690
elif node.type == NODE_PLUS:
@@ -4007,6 +4045,12 @@ def compile_divide(self, node):
40074045
def compile_remainder(self, node):
40084046
return viml_printf("(%% %s %s)", self.compile(node.left), self.compile(node.right))
40094047

4048+
def compile_lshift(self, node):
4049+
return viml_printf("(<< %s %s)", self.compile(node.left), self.compile(node.right))
4050+
4051+
def compile_rshift(self, node):
4052+
return viml_printf("(>> %s %s)", self.compile(node.left), self.compile(node.right))
4053+
40104054
def compile_not(self, node):
40114055
return viml_printf("(! %s)", self.compile(node.left))
40124056

0 commit comments

Comments
 (0)