@@ -206,6 +206,7 @@ let s:TOKEN_SHARP = 64
206206let s: TOKEN_ARROW = 65
207207let s: TOKEN_BLOB = 66
208208let s: TOKEN_LITCOPEN = 67
209+ let s: TOKEN_DOTDOT = 68
209210
210211let s: MAX_FUNC_ARGS = 20
211212
@@ -1497,9 +1498,13 @@ function! s:VimLParser.parse_cmd_let()
14971498 call self .reader.skip_white ()
14981499 let s1 = self .reader.peekn (1 )
14991500 let s2 = self .reader.peekn (2 )
1501+ " TODO check scriptversion?
1502+ if s2 == # ' ..'
1503+ let s2 = self .reader.peekn (3 )
1504+ endif
15001505
15011506 " :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 !=# ' =' )
15031508 call self .reader.seek_set (pos)
15041509 call self .parse_cmd_common ()
15051510 return
@@ -1514,8 +1519,8 @@ function! s:VimLParser.parse_cmd_let()
15141519 let node.list = lhs.list
15151520 let node.rest = lhs.rest
15161521 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) )
15191524 let node.op = s2
15201525 elseif s1 == # ' ='
15211526 call self .reader.getn (1 )
@@ -2750,9 +2755,12 @@ function! s:ExprTokenizer.get2()
27502755 if r .p (1 ) == # ' .' && r .p (2 ) == # ' .'
27512756 call r .seek_cur (3 )
27522757 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?
27532761 else
27542762 call r .seek_cur (1 )
2755- return self .token (s: TOKEN_DOT , ' .' , pos)
2763+ return self .token (s: TOKEN_DOT , ' .' , pos) " TODO check scriptversion?
27562764 endif
27572765 elseif c == # ' *'
27582766 call r .seek_cur (1 )
@@ -3209,6 +3217,7 @@ endfunction
32093217" expr5: expr6 + expr6 ..
32103218" expr6 - expr6 ..
32113219" expr6 . expr6 ..
3220+ " expr6 .. expr6 ..
32123221function ! s: ExprParser .parse_expr5 ()
32133222 let left = self .parse_expr6 ()
32143223 while s: TRUE
@@ -3226,7 +3235,13 @@ function! s:ExprParser.parse_expr5()
32263235 let node.left = left
32273236 let node.right = self .parse_expr6 ()
32283237 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?
32303245 let node = s: Node (s: NODE_CONCAT )
32313246 let node.pos = token.pos
32323247 let node.left = left
@@ -3389,7 +3404,7 @@ function! s:ExprParser.parse_expr8()
33893404 endif
33903405 let left = node
33913406 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?
33933408 let node = self .parse_dot (token, left )
33943409 if node is s: NIL
33953410 call self .reader.seek_set (pos)
@@ -3654,6 +3669,31 @@ function! s:ExprParser.parse_dot(token, left)
36543669 return node
36553670endfunction
36563671
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+
36573697function ! s: ExprParser .parse_identifier ()
36583698 call self .reader.skip_white ()
36593699 let npos = self .reader.getpos ()
0 commit comments