@@ -206,6 +206,7 @@ let s:TOKEN_SHARP = 64
206
206
let s: TOKEN_ARROW = 65
207
207
let s: TOKEN_BLOB = 66
208
208
let s: TOKEN_LITCOPEN = 67
209
+ let s: TOKEN_DOTDOT = 68
209
210
210
211
let s: MAX_FUNC_ARGS = 20
211
212
@@ -1497,9 +1498,13 @@ function! s:VimLParser.parse_cmd_let()
1497
1498
call self .reader.skip_white ()
1498
1499
let s1 = self .reader.peekn (1 )
1499
1500
let s2 = self .reader.peekn (2 )
1501
+ " TODO check scriptversion?
1502
+ if s2 == # ' ..'
1503
+ let s2 = self .reader.peekn (3 )
1504
+ endif
1500
1505
1501
1506
" :let {var-name} ..
1502
- if self .ends_excmds (s1) || (s2 !=# ' +=' && s2 !=# ' -=' && s2 !=# ' .=' && s2 !=# ' *=' && s2 !=# ' /=' && s2 !=# ' %=' && s1 !=# ' =' )
1507
+ if self .ends_excmds (s1) || (s2 !=# ' +=' && s2 !=# ' -=' && s2 !=# ' .=' && s2 !=# ' ..= ' && s2 !=# ' *=' && s2 !=# ' /=' && s2 !=# ' %=' && s1 !=# ' =' )
1503
1508
call self .reader.seek_set (pos)
1504
1509
call self .parse_cmd_common ()
1505
1510
return
@@ -1514,8 +1519,8 @@ function! s:VimLParser.parse_cmd_let()
1514
1519
let node.list = lhs.list
1515
1520
let node.rest = lhs.rest
1516
1521
let node.right = s: NIL
1517
- if s2 == # ' +=' || s2 == # ' -=' || s2 == # ' .=' || s2 == # ' *=' || s2 == # ' /=' || s2 == # ' %='
1518
- call self .reader.getn (2 )
1522
+ if s2 == # ' +=' || s2 == # ' -=' || s2 == # ' .=' || s2 == # ' ..= ' || s2 == # ' *=' || s2 == # ' /=' || s2 == # ' %='
1523
+ call self .reader.getn (len (s2) )
1519
1524
let node.op = s2
1520
1525
elseif s1 == # ' ='
1521
1526
call self .reader.getn (1 )
@@ -2750,9 +2755,12 @@ function! s:ExprTokenizer.get2()
2750
2755
if r .p (1 ) == # ' .' && r .p (2 ) == # ' .'
2751
2756
call r .seek_cur (3 )
2752
2757
return self .token (s: TOKEN_DOTDOTDOT , ' ...' , pos)
2758
+ elseif r .p (1 ) == # ' .'
2759
+ call r .seek_cur (2 )
2760
+ return self .token (s: TOKEN_DOTDOT , ' ..' , pos) " TODO check scriptversion?
2753
2761
else
2754
2762
call r .seek_cur (1 )
2755
- return self .token (s: TOKEN_DOT , ' .' , pos)
2763
+ return self .token (s: TOKEN_DOT , ' .' , pos) " TODO check scriptversion?
2756
2764
endif
2757
2765
elseif c == # ' *'
2758
2766
call r .seek_cur (1 )
@@ -3209,6 +3217,7 @@ endfunction
3209
3217
" expr5: expr6 + expr6 ..
3210
3218
" expr6 - expr6 ..
3211
3219
" expr6 . expr6 ..
3220
+ " expr6 .. expr6 ..
3212
3221
function ! s: ExprParser .parse_expr5 ()
3213
3222
let left = self .parse_expr6 ()
3214
3223
while s: TRUE
@@ -3226,7 +3235,13 @@ function! s:ExprParser.parse_expr5()
3226
3235
let node.left = left
3227
3236
let node.right = self .parse_expr6 ()
3228
3237
let left = node
3229
- elseif token.type == s: TOKEN_DOT
3238
+ elseif token.type == s: TOKEN_DOTDOT " TODO check scriptversion?
3239
+ let node = s: Node (s: NODE_CONCAT )
3240
+ let node.pos = token.pos
3241
+ let node.left = left
3242
+ let node.right = self .parse_expr6 ()
3243
+ let left = node
3244
+ elseif token.type == s: TOKEN_DOT " TODO check scriptversion?
3230
3245
let node = s: Node (s: NODE_CONCAT )
3231
3246
let node.pos = token.pos
3232
3247
let node.left = left
@@ -3389,7 +3404,7 @@ function! s:ExprParser.parse_expr8()
3389
3404
endif
3390
3405
let left = node
3391
3406
unlet node
3392
- elseif ! s: iswhite (c ) && token.type == s: TOKEN_DOT
3407
+ elseif ! s: iswhite (c ) && token.type == s: TOKEN_DOT " TODO check scriptversion?
3393
3408
let node = self .parse_dot (token, left )
3394
3409
if node is s: NIL
3395
3410
call self .reader.seek_set (pos)
@@ -3654,6 +3669,31 @@ function! s:ExprParser.parse_dot(token, left)
3654
3669
return node
3655
3670
endfunction
3656
3671
3672
+ " CONCAT
3673
+ " str ".." expr6 => (concat str expr6)
3674
+ function ! s: ExprParser .parse_concat (token, left )
3675
+ if a: left .type != s: NODE_IDENTIFIER && a: left .type != s: NODE_CURLYNAME && a: left .type != s: NODE_DICT && a: left .type != s: NODE_SUBSCRIPT && a: left .type != s: NODE_CALL && a: left .type != s: NODE_DOT
3676
+ return s: NIL
3677
+ endif
3678
+ if ! s: iswordc (self .reader.p (0 ))
3679
+ return s: NIL
3680
+ endif
3681
+ let pos = self .reader.getpos ()
3682
+ let name = self .reader.read_word ()
3683
+ if s: isnamec (self .reader.p (0 ))
3684
+ " XXX: foo is str => ok, foo is obj => invalid expression
3685
+ " foo.s:bar or foo.bar#baz
3686
+ return s: NIL
3687
+ endif
3688
+ let node = s: Node (s: NODE_CONCAT )
3689
+ let node.pos = a: token .pos
3690
+ let node.left = a: left
3691
+ let node.right = s: Node (s: NODE_IDENTIFIER )
3692
+ let node.right .pos = pos
3693
+ let node.right .value = name
3694
+ return node
3695
+ endfunction
3696
+
3657
3697
function ! s: ExprParser .parse_identifier ()
3658
3698
call self .reader.skip_white ()
3659
3699
let npos = self .reader.getpos ()
0 commit comments