@@ -397,6 +397,7 @@ var TOKEN_DOTDOTDOT = 63;
397
397
var TOKEN_SHARP = 64 ;
398
398
var TOKEN_ARROW = 65 ;
399
399
var TOKEN_BLOB = 66 ;
400
+ var TOKEN_DOTDOT = 67 ;
400
401
var MAX_FUNC_ARGS = 20 ;
401
402
function isalpha ( c ) {
402
403
return viml_eqregh ( c , "^[A-Za-z]$" ) ;
@@ -1798,8 +1799,12 @@ VimLParser.prototype.parse_cmd_let = function() {
1798
1799
this . reader . skip_white ( ) ;
1799
1800
var s1 = this . reader . peekn ( 1 ) ;
1800
1801
var s2 = this . reader . peekn ( 2 ) ;
1802
+ // TODO check scriptversion?
1803
+ if ( s2 == ".." ) {
1804
+ var s2 = this . reader . peekn ( 3 ) ;
1805
+ }
1801
1806
// :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 != "=" ) {
1803
1808
this . reader . seek_set ( pos ) ;
1804
1809
this . parse_cmd_common ( ) ;
1805
1810
return ;
@@ -1813,8 +1818,8 @@ VimLParser.prototype.parse_cmd_let = function() {
1813
1818
node . list = lhs . list ;
1814
1819
node . rest = lhs . rest ;
1815
1820
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 ) ) ;
1818
1823
node . op = s2 ;
1819
1824
}
1820
1825
else if ( s1 == "=" ) {
@@ -2522,9 +2527,15 @@ ExprTokenizer.prototype.get2 = function() {
2522
2527
r . seek_cur ( 3 ) ;
2523
2528
return this . token ( TOKEN_DOTDOTDOT , "..." , pos ) ;
2524
2529
}
2530
+ else if ( r . p ( 1 ) == "." ) {
2531
+ r . seek_cur ( 2 ) ;
2532
+ return this . token ( TOKEN_DOTDOT , ".." , pos ) ;
2533
+ // TODO check scriptversion?
2534
+ }
2525
2535
else {
2526
2536
r . seek_cur ( 1 ) ;
2527
2537
return this . token ( TOKEN_DOT , "." , pos ) ;
2538
+ // TODO check scriptversion?
2528
2539
}
2529
2540
}
2530
2541
else if ( c == "*" ) {
@@ -3010,6 +3021,7 @@ ExprParser.prototype.parse_expr4 = function() {
3010
3021
// expr5: expr6 + expr6 ..
3011
3022
// expr6 - expr6 ..
3012
3023
// expr6 . expr6 ..
3024
+ // expr6 .. expr6 ..
3013
3025
ExprParser . prototype . parse_expr5 = function ( ) {
3014
3026
var left = this . parse_expr6 ( ) ;
3015
3027
while ( TRUE ) {
@@ -3029,7 +3041,16 @@ ExprParser.prototype.parse_expr5 = function() {
3029
3041
node . right = this . parse_expr6 ( ) ;
3030
3042
var left = node ;
3031
3043
}
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
+ }
3032
3052
else if ( token . type == TOKEN_DOT ) {
3053
+ // TODO check scriptversion?
3033
3054
var node = Node ( NODE_CONCAT ) ;
3034
3055
node . pos = token . pos ;
3035
3056
node . left = left ;
@@ -3207,6 +3228,7 @@ ExprParser.prototype.parse_expr8 = function() {
3207
3228
delete node ;
3208
3229
}
3209
3230
else if ( ! iswhite ( c ) && token . type == TOKEN_DOT ) {
3231
+ // TODO check scriptversion?
3210
3232
var node = this . parse_dot ( token , left ) ;
3211
3233
if ( node === NIL ) {
3212
3234
this . reader . seek_set ( pos ) ;
@@ -3489,6 +3511,31 @@ ExprParser.prototype.parse_dot = function(token, left) {
3489
3511
return node ;
3490
3512
}
3491
3513
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
+
3492
3539
ExprParser . prototype . parse_identifier = function ( ) {
3493
3540
this . reader . skip_white ( ) ;
3494
3541
var npos = this . reader . getpos ( ) ;
0 commit comments