Skip to content

Commit e6cf24e

Browse files
committed
Gen
1 parent 2728ffe commit e6cf24e

File tree

2 files changed

+93
-6
lines changed

2 files changed

+93
-6
lines changed

js/vimlparser.js

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ var TOKEN_DOTDOTDOT = 63;
397397
var TOKEN_SHARP = 64;
398398
var TOKEN_ARROW = 65;
399399
var TOKEN_BLOB = 66;
400+
var TOKEN_DOTDOT = 67;
400401
var MAX_FUNC_ARGS = 20;
401402
function 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 ..
30133025
ExprParser.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+
34923539
ExprParser.prototype.parse_identifier = function() {
34933540
this.reader.skip_white();
34943541
var npos = this.reader.getpos();

py/vimlparser.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ def viml_type(obj):
351351
TOKEN_SHARP = 64
352352
TOKEN_ARROW = 65
353353
TOKEN_BLOB = 66
354+
TOKEN_DOTDOT = 67
354355
MAX_FUNC_ARGS = 20
355356
def isalpha(c):
356357
return viml_eqregh(c, "^[A-Za-z]$")
@@ -1426,8 +1427,11 @@ def parse_cmd_let(self):
14261427
self.reader.skip_white()
14271428
s1 = self.reader.peekn(1)
14281429
s2 = self.reader.peekn(2)
1430+
# TODO check scriptversion?
1431+
if s2 == "..":
1432+
s2 = self.reader.peekn(3)
14291433
# :let {var-name} ..
1430-
if self.ends_excmds(s1) or s2 != "+=" and s2 != "-=" and s2 != ".=" and s2 != "*=" and s2 != "/=" and s2 != "%=" and s1 != "=":
1434+
if self.ends_excmds(s1) or s2 != "+=" and s2 != "-=" and s2 != ".=" and s2 != "..=" and s2 != "*=" and s2 != "/=" and s2 != "%=" and s1 != "=":
14311435
self.reader.seek_set(pos)
14321436
self.parse_cmd_common()
14331437
return
@@ -1440,8 +1444,8 @@ def parse_cmd_let(self):
14401444
node.list = lhs.list
14411445
node.rest = lhs.rest
14421446
node.right = NIL
1443-
if s2 == "+=" or s2 == "-=" or s2 == ".=" or s2 == "*=" or s2 == "/=" or s2 == "%=":
1444-
self.reader.getn(2)
1447+
if s2 == "+=" or s2 == "-=" or s2 == ".=" or s2 == "..=" or s2 == "*=" or s2 == "/=" or s2 == "%=":
1448+
self.reader.getn(viml_len(s2))
14451449
node.op = s2
14461450
elif s1 == "=":
14471451
self.reader.getn(1)
@@ -2001,9 +2005,14 @@ def get2(self):
20012005
if r.p(1) == "." and r.p(2) == ".":
20022006
r.seek_cur(3)
20032007
return self.token(TOKEN_DOTDOTDOT, "...", pos)
2008+
elif r.p(1) == ".":
2009+
r.seek_cur(2)
2010+
return self.token(TOKEN_DOTDOT, "..", pos)
2011+
# TODO check scriptversion?
20042012
else:
20052013
r.seek_cur(1)
20062014
return self.token(TOKEN_DOT, ".", pos)
2015+
# TODO check scriptversion?
20072016
elif c == "*":
20082017
r.seek_cur(1)
20092018
return self.token(TOKEN_STAR, "*", pos)
@@ -2398,6 +2407,7 @@ def parse_expr4(self):
23982407
# expr5: expr6 + expr6 ..
23992408
# expr6 - expr6 ..
24002409
# expr6 . expr6 ..
2410+
# expr6 .. expr6 ..
24012411
def parse_expr5(self):
24022412
left = self.parse_expr6()
24032413
while TRUE:
@@ -2415,7 +2425,15 @@ def parse_expr5(self):
24152425
node.left = left
24162426
node.right = self.parse_expr6()
24172427
left = node
2428+
elif token.type == TOKEN_DOTDOT:
2429+
# TODO check scriptversion?
2430+
node = Node(NODE_CONCAT)
2431+
node.pos = token.pos
2432+
node.left = left
2433+
node.right = self.parse_expr6()
2434+
left = node
24182435
elif token.type == TOKEN_DOT:
2436+
# TODO check scriptversion?
24192437
node = Node(NODE_CONCAT)
24202438
node.pos = token.pos
24212439
node.left = left
@@ -2559,6 +2577,7 @@ def parse_expr8(self):
25592577
left = node
25602578
del node
25612579
elif not iswhite(c) and token.type == TOKEN_DOT:
2580+
# TODO check scriptversion?
25622581
node = self.parse_dot(token, left)
25632582
if node is NIL:
25642583
self.reader.seek_set(pos)
@@ -2781,6 +2800,27 @@ def parse_dot(self, token, left):
27812800
node.right.value = name
27822801
return node
27832802

2803+
# CONCAT
2804+
# str ".." expr6 => (concat str expr6)
2805+
def parse_concat(self, token, left):
2806+
if left.type != NODE_IDENTIFIER and left.type != NODE_CURLYNAME and left.type != NODE_DICT and left.type != NODE_SUBSCRIPT and left.type != NODE_CALL and left.type != NODE_DOT:
2807+
return NIL
2808+
if not iswordc(self.reader.p(0)):
2809+
return NIL
2810+
pos = self.reader.getpos()
2811+
name = self.reader.read_word()
2812+
if isnamec(self.reader.p(0)):
2813+
# XXX: foo is str => ok, foo is obj => invalid expression
2814+
# foo.s:bar or foo.bar#baz
2815+
return NIL
2816+
node = Node(NODE_CONCAT)
2817+
node.pos = token.pos
2818+
node.left = left
2819+
node.right = Node(NODE_IDENTIFIER)
2820+
node.right.pos = pos
2821+
node.right.value = name
2822+
return node
2823+
27842824
def parse_identifier(self):
27852825
self.reader.skip_white()
27862826
npos = self.reader.getpos()

0 commit comments

Comments
 (0)