Skip to content

Commit 14192b1

Browse files
committed
Fix heredoc
1 parent 2b5e08a commit 14192b1

File tree

3 files changed

+51
-30
lines changed

3 files changed

+51
-30
lines changed

autoload/vimlparser.vim

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,24 +1493,22 @@ function! s:VimLParser.parse_heredoc()
14931493
let node.rlist = []
14941494
let node.body = []
14951495

1496-
let words = []
14971496
while s:TRUE
14981497
call self.reader.skip_white()
14991498
let key = self.reader.read_alpha()
15001499
if key == ''
15011500
break
15021501
endif
1503-
if key !~# '^[a-z]'
1502+
if !s:islower(key[0])
15041503
let node.op = key
15051504
break
15061505
else
1507-
call add(words, key)
1506+
call add(node.rlist, key)
15081507
endif
15091508
endwhile
1510-
if node.op ==# ''
1511-
return s:NIL
1509+
if node.op ==# '' || node.op !~# '^[^a-z]\S\+$'
1510+
throw s:Err('E172: Missing marker', self.reader.getpos())
15121511
endif
1513-
let node.rlist = words
15141512
call self.parse_trail()
15151513
while s:TRUE
15161514
if self.reader.peek() ==# '<EOF>'
@@ -1523,7 +1521,7 @@ function! s:VimLParser.parse_heredoc()
15231521
call add(node.body, line)
15241522
call self.reader.get()
15251523
endwhile
1526-
return s:NIL
1524+
throw s:Err(printf("E990: Missing end marker '%s'", node.op), self.reader.getpos())
15271525
endfunction
15281526

15291527
function! s:VimLParser.parse_cmd_let()
@@ -4897,9 +4895,18 @@ function! s:Compiler.compile_lambda(node)
48974895
endfunction
48984896

48994897
function! s:Compiler.compile_heredoc(node)
4900-
let rlist = map(a:node.rlist, 'self.escape_string(v:val)')
4901-
let body = map(a:node.body, 'self.escape_string(v:val)')
4902-
return printf('(heredoc (list %s) %s (list %s))', join(rlist, ' '), self.escape_string(a:node.op), join(body, ' '))
4898+
if empty(a:node.rlist)
4899+
let rlist = '(list)'
4900+
else
4901+
let rlist = '(list ' . join(map(a:node.rlist, 'self.escape_string(v:val)'), ' ') . ')'
4902+
endif
4903+
if empty(a:node.body)
4904+
let body = '(list)'
4905+
else
4906+
let body = '(list ' . join(map(a:node.body, 'self.escape_string(v:val)'), ' ') . ')'
4907+
endif
4908+
let op = self.escape_string(a:node.op)
4909+
return printf('(heredoc %s %s %s)', rlist, op, body)
49034910
endfunction
49044911

49054912
" TODO: under construction

js/vimlparser.js

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,25 +1779,23 @@ VimLParser.prototype.parse_heredoc = function() {
17791779
node.op = "";
17801780
node.rlist = [];
17811781
node.body = [];
1782-
var words = [];
17831782
while (TRUE) {
17841783
this.reader.skip_white();
17851784
var key = this.reader.read_alpha();
17861785
if (key == "") {
17871786
break;
17881787
}
1789-
if (!viml_eqregh(key, "^[a-z]")) {
1788+
if (!islower(key[0])) {
17901789
node.op = key;
17911790
break;
17921791
}
17931792
else {
1794-
viml_add(words, key);
1793+
viml_add(node.rlist, key);
17951794
}
17961795
}
1797-
if (node.op == "") {
1798-
return NIL;
1796+
if (node.op == "" || !viml_eqregh(node.op, "^[^a-z]\\S\\+$")) {
1797+
throw Err("E172: Missing marker", this.reader.getpos());
17991798
}
1800-
node.rlist = words;
18011799
this.parse_trail();
18021800
while (TRUE) {
18031801
if (this.reader.peek() == "<EOF>") {
@@ -1810,7 +1808,7 @@ VimLParser.prototype.parse_heredoc = function() {
18101808
viml_add(node.body, line);
18111809
this.reader.get();
18121810
}
1813-
return NIL;
1811+
throw Err(viml_printf("E990: Missing end marker '%s'", node.op), this.reader.getpos());
18141812
}
18151813

18161814
VimLParser.prototype.parse_cmd_let = function() {
@@ -4884,9 +4882,20 @@ Compiler.prototype.compile_lambda = function(node) {
48844882
}
48854883

48864884
Compiler.prototype.compile_heredoc = function(node) {
4887-
var rlist = node.rlist.map((function(vval) { return this.escape_string(vval); }).bind(this));
4888-
var body = node.body.map((function(vval) { return this.escape_string(vval); }).bind(this));
4889-
return viml_printf("(heredoc (list %s) %s (list %s))", viml_join(rlist, " "), this.escape_string(node.op), viml_join(body, " "));
4885+
if (viml_empty(node.rlist)) {
4886+
var rlist = "(list)";
4887+
}
4888+
else {
4889+
var rlist = "(list " + viml_join(node.rlist.map((function(vval) { return this.escape_string(vval); }).bind(this)), " ") + ")";
4890+
}
4891+
if (viml_empty(node.body)) {
4892+
var body = "(list)";
4893+
}
4894+
else {
4895+
var body = "(list " + viml_join(node.body.map((function(vval) { return this.escape_string(vval); }).bind(this)), " ") + ")";
4896+
}
4897+
var op = this.escape_string(node.op);
4898+
return viml_printf("(heredoc %s %s %s)", rlist, op, body);
48904899
}
48914900

48924901
// TODO: under construction

py/vimlparser.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,20 +1410,18 @@ def parse_heredoc(self):
14101410
node.op = ""
14111411
node.rlist = []
14121412
node.body = []
1413-
words = []
14141413
while TRUE:
14151414
self.reader.skip_white()
14161415
key = self.reader.read_alpha()
14171416
if key == "":
14181417
break
1419-
if not viml_eqregh(key, "^[a-z]"):
1418+
if not islower(key[0]):
14201419
node.op = key
14211420
break
14221421
else:
1423-
viml_add(words, key)
1424-
if node.op == "":
1425-
return NIL
1426-
node.rlist = words
1422+
viml_add(node.rlist, key)
1423+
if node.op == "" or not viml_eqregh(node.op, "^[^a-z]\\S\\+$"):
1424+
raise VimLParserException(Err("E172: Missing marker", self.reader.getpos()))
14271425
self.parse_trail()
14281426
while TRUE:
14291427
if self.reader.peek() == "<EOF>":
@@ -1433,7 +1431,7 @@ def parse_heredoc(self):
14331431
return node
14341432
viml_add(node.body, line)
14351433
self.reader.get()
1436-
return NIL
1434+
raise VimLParserException(Err(viml_printf("E990: Missing end marker '%s'", node.op), self.reader.getpos()))
14371435

14381436
def parse_cmd_let(self):
14391437
pos = self.reader.tell()
@@ -3825,9 +3823,16 @@ def compile_lambda(self, node):
38253823
return viml_printf("(lambda (%s) %s)", viml_join(rlist, " "), self.compile(node.left))
38263824

38273825
def compile_heredoc(self, node):
3828-
rlist = [self.escape_string(vval) for vval in node.rlist]
3829-
body = [self.escape_string(vval) for vval in node.body]
3830-
return viml_printf("(heredoc (list %s) %s (list %s))", viml_join(rlist, " "), self.escape_string(node.op), viml_join(body, " "))
3826+
if viml_empty(node.rlist):
3827+
rlist = "(list)"
3828+
else:
3829+
rlist = "(list " + viml_join([self.escape_string(vval) for vval in node.rlist], " ") + ")"
3830+
if viml_empty(node.body):
3831+
body = "(list)"
3832+
else:
3833+
body = "(list " + viml_join([self.escape_string(vval) for vval in node.body], " ") + ")"
3834+
op = self.escape_string(node.op)
3835+
return viml_printf("(heredoc %s %s %s)", rlist, op, body)
38313836

38323837
# TODO: under construction
38333838
class RegexpParser:

0 commit comments

Comments
 (0)