@@ -397,6 +397,7 @@ var TOKEN_DOTDOTDOT = 63;
397397var TOKEN_SHARP = 64 ;
398398var TOKEN_ARROW = 65 ;
399399var TOKEN_BLOB = 66 ;
400+ var TOKEN_DOTDOT = 67 ;
400401var MAX_FUNC_ARGS = 20 ;
401402function isalpha ( c ) {
402403 return viml_eqregh ( c , "^[A-Za-z]$" ) ;
@@ -1798,8 +1799,12 @@ VimLParser.prototype.parse_cmd_let = function() {
17981799 this . reader . skip_white ( ) ;
17991800 var s1 = this . reader . peekn ( 1 ) ;
18001801 var s2 = this . reader . peekn ( 2 ) ;
1802+ // TODO check scriptversion?
1803+ if ( s2 == ".." ) {
1804+ var s2 = this . reader . peekn ( 3 ) ;
1805+ }
18011806 // :let {var-name} ..
1802- if ( this . ends_excmds ( s1 ) || s2 != "+=" && s2 != "-=" && s2 != ".=" && s2 != "*=" && s2 != "/=" && s2 != "%=" && s1 != "=" ) {
1807+ if ( this . ends_excmds ( s1 ) || s2 != "+=" && s2 != "-=" && s2 != ".=" && s2 != "..=" && s2 != " *=" && s2 != "/=" && s2 != "%=" && s1 != "=" ) {
18031808 this . reader . seek_set ( pos ) ;
18041809 this . parse_cmd_common ( ) ;
18051810 return ;
@@ -1813,8 +1818,8 @@ VimLParser.prototype.parse_cmd_let = function() {
18131818 node . list = lhs . list ;
18141819 node . rest = lhs . rest ;
18151820 node . right = NIL ;
1816- if ( s2 == "+=" || s2 == "-=" || s2 == ".=" || s2 == "*=" || s2 == "/=" || s2 == "%=" ) {
1817- this . reader . getn ( 2 ) ;
1821+ if ( s2 == "+=" || s2 == "-=" || s2 == ".=" || s2 == "..=" || s2 == " *=" || s2 == "/=" || s2 == "%=" ) {
1822+ this . reader . getn ( viml_len ( s2 ) ) ;
18181823 node . op = s2 ;
18191824 }
18201825 else if ( s1 == "=" ) {
@@ -2522,9 +2527,15 @@ ExprTokenizer.prototype.get2 = function() {
25222527 r . seek_cur ( 3 ) ;
25232528 return this . token ( TOKEN_DOTDOTDOT , "..." , pos ) ;
25242529 }
2530+ else if ( r . p ( 1 ) == "." ) {
2531+ r . seek_cur ( 2 ) ;
2532+ return this . token ( TOKEN_DOTDOT , ".." , pos ) ;
2533+ // TODO check scriptversion?
2534+ }
25252535 else {
25262536 r . seek_cur ( 1 ) ;
25272537 return this . token ( TOKEN_DOT , "." , pos ) ;
2538+ // TODO check scriptversion?
25282539 }
25292540 }
25302541 else if ( c == "*" ) {
@@ -3010,6 +3021,7 @@ ExprParser.prototype.parse_expr4 = function() {
30103021// expr5: expr6 + expr6 ..
30113022// expr6 - expr6 ..
30123023// expr6 . expr6 ..
3024+ // expr6 .. expr6 ..
30133025ExprParser . prototype . parse_expr5 = function ( ) {
30143026 var left = this . parse_expr6 ( ) ;
30153027 while ( TRUE ) {
@@ -3029,7 +3041,16 @@ ExprParser.prototype.parse_expr5 = function() {
30293041 node . right = this . parse_expr6 ( ) ;
30303042 var left = node ;
30313043 }
3044+ else if ( token . type == TOKEN_DOTDOT ) {
3045+ // TODO check scriptversion?
3046+ var node = Node ( NODE_CONCAT ) ;
3047+ node . pos = token . pos ;
3048+ node . left = left ;
3049+ node . right = this . parse_expr6 ( ) ;
3050+ var left = node ;
3051+ }
30323052 else if ( token . type == TOKEN_DOT ) {
3053+ // TODO check scriptversion?
30333054 var node = Node ( NODE_CONCAT ) ;
30343055 node . pos = token . pos ;
30353056 node . left = left ;
@@ -3207,6 +3228,7 @@ ExprParser.prototype.parse_expr8 = function() {
32073228 delete node ;
32083229 }
32093230 else if ( ! iswhite ( c ) && token . type == TOKEN_DOT ) {
3231+ // TODO check scriptversion?
32103232 var node = this . parse_dot ( token , left ) ;
32113233 if ( node === NIL ) {
32123234 this . reader . seek_set ( pos ) ;
@@ -3489,6 +3511,31 @@ ExprParser.prototype.parse_dot = function(token, left) {
34893511 return node ;
34903512}
34913513
3514+ // CONCAT
3515+ // str ".." expr6 => (concat str expr6)
3516+ ExprParser . prototype . parse_concat = function ( token , left ) {
3517+ if ( left . type != NODE_IDENTIFIER && left . type != NODE_CURLYNAME && left . type != NODE_DICT && left . type != NODE_SUBSCRIPT && left . type != NODE_CALL && left . type != NODE_DOT ) {
3518+ return NIL ;
3519+ }
3520+ if ( ! iswordc ( this . reader . p ( 0 ) ) ) {
3521+ return NIL ;
3522+ }
3523+ var pos = this . reader . getpos ( ) ;
3524+ var name = this . reader . read_word ( ) ;
3525+ if ( isnamec ( this . reader . p ( 0 ) ) ) {
3526+ // XXX: foo is str => ok, foo is obj => invalid expression
3527+ // foo.s:bar or foo.bar#baz
3528+ return NIL ;
3529+ }
3530+ var node = Node ( NODE_CONCAT ) ;
3531+ node . pos = token . pos ;
3532+ node . left = left ;
3533+ node . right = Node ( NODE_IDENTIFIER ) ;
3534+ node . right . pos = pos ;
3535+ node . right . value = name ;
3536+ return node ;
3537+ }
3538+
34923539ExprParser . prototype . parse_identifier = function ( ) {
34933540 this . reader . skip_white ( ) ;
34943541 var npos = this . reader . getpos ( ) ;
0 commit comments