Skip to content

Commit cd0e7d5

Browse files
committed
add -> operator
1 parent 1d130bc commit cd0e7d5

File tree

5 files changed

+76
-0
lines changed

5 files changed

+76
-0
lines changed

autoload/vimlparser.vim

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ let s:NODE_CURLYNAMEEXPR = 91
139139
let s:NODE_LAMBDA = 92
140140
let s:NODE_BLOB = 93
141141
let s:NODE_CONST = 94
142+
let s:NODE_METHOD = 95
142143

143144
let s:TOKEN_EOF = 1
144145
let s:TOKEN_EOL = 2
@@ -394,6 +395,7 @@ endfunction
394395
" PLUS .left
395396
" SUBSCRIPT .left .right
396397
" SLICE .left .rlist
398+
" METHOD .left .right .lambda_rlist
397399
" CALL .left .rlist
398400
" DOT .left .right
399401
" NUMBER .value
@@ -3896,6 +3898,9 @@ endfunction
38963898
" expr8: expr8[expr1]
38973899
" expr8[expr1 : expr1]
38983900
" expr8.name
3901+
" expr8->name(expr1, ...)
3902+
" expr8->s:user_func(expr1, ...)
3903+
" expr8->{lambda}(expr1, ...)
38993904
" expr8(expr1, ...)
39003905
function! s:ExprParser.parse_expr8() abort
39013906
let left = self.parse_expr9()
@@ -3950,6 +3955,17 @@ function! s:ExprParser.parse_expr8() abort
39503955
endif
39513956
endif
39523957
unlet node
3958+
elseif token.type ==# s:TOKEN_ARROW
3959+
let node = s:Node(s:NODE_METHOD)
3960+
let node.pos = token.pos
3961+
let node.left = left
3962+
let node.right = self.parse_expr8()
3963+
let node.lambda_rlist = s:NIL
3964+
if node.right.type !=# s:NODE_CALL
3965+
throw s:Err('Invalid method syntax', node.right.pos)
3966+
endif
3967+
let left = node
3968+
unlet node
39533969
elseif token.type ==# s:TOKEN_POPEN
39543970
let node = s:Node(s:NODE_CALL)
39553971
let node.pos = token.pos
@@ -4906,6 +4922,8 @@ function! s:Compiler.compile(node) abort
49064922
return self.compile_slice(a:node)
49074923
elseif a:node.type ==# s:NODE_DOT
49084924
return self.compile_dot(a:node)
4925+
elseif a:node.type ==# s:NODE_METHOD
4926+
return self.compile_method(a:node)
49094927
elseif a:node.type ==# s:NODE_CALL
49104928
return self.compile_call(a:node)
49114929
elseif a:node.type ==# s:NODE_NUMBER
@@ -5345,6 +5363,10 @@ function! s:Compiler.compile_dot(node) abort
53455363
return printf('(dot %s %s)', self.compile(a:node.left), self.compile(a:node.right))
53465364
endfunction
53475365

5366+
function! s:Compiler.compile_method(node) abort
5367+
return printf('(method %s %s)', self.compile(a:node.left), self.compile(a:node.right))
5368+
endfunction
5369+
53485370
function! s:Compiler.compile_call(node) abort
53495371
let rlist = map(a:node.rlist, 'self.compile(v:val)')
53505372
if empty(rlist)

js/vimlparser.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ var NODE_CURLYNAMEEXPR = 91;
320320
var NODE_LAMBDA = 92;
321321
var NODE_BLOB = 93;
322322
var NODE_CONST = 94;
323+
var NODE_METHOD = 95;
323324
var TOKEN_EOF = 1;
324325
var TOKEN_EOL = 2;
325326
var TOKEN_SPACE = 3;
@@ -572,6 +573,7 @@ function ExArg() {
572573
// PLUS .left
573574
// SUBSCRIPT .left .right
574575
// SLICE .left .rlist
576+
// METHOD .left .right .lambda_rlist
575577
// CALL .left .rlist
576578
// DOT .left .right
577579
// NUMBER .value
@@ -3260,6 +3262,9 @@ ExprParser.prototype.parse_expr7 = function() {
32603262
// expr8: expr8[expr1]
32613263
// expr8[expr1 : expr1]
32623264
// expr8.name
3265+
// expr8->name(expr1, ...)
3266+
// expr8->s:user_func(expr1, ...)
3267+
// expr8->{lambda}(expr1, ...)
32633268
// expr8(expr1, ...)
32643269
ExprParser.prototype.parse_expr8 = function() {
32653270
var left = this.parse_expr9();
@@ -3317,6 +3322,18 @@ ExprParser.prototype.parse_expr8 = function() {
33173322
}
33183323
delete node;
33193324
}
3325+
else if (token.type == TOKEN_ARROW) {
3326+
var node = Node(NODE_METHOD);
3327+
node.pos = token.pos;
3328+
node.left = left;
3329+
node.right = this.parse_expr8();
3330+
node.lambda_rlist = NIL;
3331+
if (node.right.type != NODE_CALL) {
3332+
throw Err("Invalid method syntax", node.right.pos);
3333+
}
3334+
var left = node;
3335+
delete node;
3336+
}
33203337
else if (token.type == TOKEN_POPEN) {
33213338
var node = Node(NODE_CALL);
33223339
node.pos = token.pos;
@@ -4393,6 +4410,9 @@ Compiler.prototype.compile = function(node) {
43934410
else if (node.type == NODE_DOT) {
43944411
return this.compile_dot(node);
43954412
}
4413+
else if (node.type == NODE_METHOD) {
4414+
return this.compile_method(node);
4415+
}
43964416
else if (node.type == NODE_CALL) {
43974417
return this.compile_call(node);
43984418
}
@@ -4860,6 +4880,10 @@ Compiler.prototype.compile_dot = function(node) {
48604880
return viml_printf("(dot %s %s)", this.compile(node.left), this.compile(node.right));
48614881
}
48624882

4883+
Compiler.prototype.compile_method = function(node) {
4884+
return viml_printf("(method %s %s)", this.compile(node.left), this.compile(node.right));
4885+
}
4886+
48634887
Compiler.prototype.compile_call = function(node) {
48644888
var rlist = node.rlist.map((function(vval) { return this.compile(vval); }).bind(this));
48654889
if (viml_empty(rlist)) {

py/vimlparser.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ def viml_stridx(a, b):
306306
NODE_LAMBDA = 92
307307
NODE_BLOB = 93
308308
NODE_CONST = 94
309+
NODE_METHOD = 95
309310
TOKEN_EOF = 1
310311
TOKEN_EOL = 2
311312
TOKEN_SPACE = 3
@@ -560,6 +561,7 @@ def ExArg():
560561
# PLUS .left
561562
# SUBSCRIPT .left .right
562563
# SLICE .left .rlist
564+
# METHOD .left .right .lambda_rlist
563565
# CALL .left .rlist
564566
# DOT .left .right
565567
# NUMBER .value
@@ -2656,6 +2658,9 @@ def parse_expr7(self):
26562658
# expr8: expr8[expr1]
26572659
# expr8[expr1 : expr1]
26582660
# expr8.name
2661+
# expr8->name(expr1, ...)
2662+
# expr8->s:user_func(expr1, ...)
2663+
# expr8->{lambda}(expr1, ...)
26592664
# expr8(expr1, ...)
26602665
def parse_expr8(self):
26612666
left = self.parse_expr9()
@@ -2703,6 +2708,16 @@ def parse_expr8(self):
27032708
raise VimLParserException(Err(viml_printf("unexpected token: %s", token.value), token.pos))
27042709
left = node
27052710
del node
2711+
elif token.type == TOKEN_ARROW:
2712+
node = Node(NODE_METHOD)
2713+
node.pos = token.pos
2714+
node.left = left
2715+
node.right = self.parse_expr8()
2716+
node.lambda_rlist = NIL
2717+
if node.right.type != NODE_CALL:
2718+
raise VimLParserException(Err("Invalid method syntax", node.right.pos))
2719+
left = node
2720+
del node
27062721
elif token.type == TOKEN_POPEN:
27072722
node = Node(NODE_CALL)
27082723
node.pos = token.pos
@@ -3525,6 +3540,8 @@ def compile(self, node):
35253540
return self.compile_slice(node)
35263541
elif node.type == NODE_DOT:
35273542
return self.compile_dot(node)
3543+
elif node.type == NODE_METHOD:
3544+
return self.compile_method(node)
35283545
elif node.type == NODE_CALL:
35293546
return self.compile_call(node)
35303547
elif node.type == NODE_NUMBER:
@@ -3874,6 +3891,9 @@ def compile_slice(self, node):
38743891
def compile_dot(self, node):
38753892
return viml_printf("(dot %s %s)", self.compile(node.left), self.compile(node.right))
38763893

3894+
def compile_method(self, node):
3895+
return viml_printf("(method %s %s)", self.compile(node.left), self.compile(node.right))
3896+
38773897
def compile_call(self, node):
38783898
rlist = [self.compile(vval) for vval in node.rlist]
38793899
if viml_empty(rlist):

test/test_method.ok

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
(echo (method 'alice' (s:hello)))
2+
(echo (method 'alice' (s:hello 'bob')))
3+
(echo (method (list 1 2 3) (map (lambda (i n) (* n 2)))))
4+
(echo (method 'john' ((lambda (s) (concat 'hello ' s)))))
5+
(echo (method 'john' ((lambda (s b) (concat (concat (concat (concat 'hello ' s) ' ... and goodbye ') b) '!')) 'bob')))

test/test_method.vim

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
echo 'alice'->s:hello()
2+
echo 'alice'->s:hello('bob')
3+
echo [1,2,3]->map({i,n -> n * 2})
4+
echo 'john'->{s -> 'hello ' .. s }()
5+
echo 'john'->{s,b -> 'hello ' .. s .. ' ... and goodbye ' .. b .. '!' }('bob')

0 commit comments

Comments
 (0)