@@ -314,6 +314,7 @@ var NODE_CURLYNAMEPART = 90;
314
314
var NODE_CURLYNAMEEXPR = 91 ;
315
315
var NODE_LAMBDA = 92 ;
316
316
var NODE_BLOB = 93 ;
317
+ var NODE_HEREDOC = 94 ;
317
318
var TOKEN_EOF = 1 ;
318
319
var TOKEN_EOL = 2 ;
319
320
var TOKEN_SPACE = 3 ;
@@ -382,6 +383,7 @@ var TOKEN_ARROW = 65;
382
383
var TOKEN_BLOB = 66 ;
383
384
var TOKEN_LITCOPEN = 67 ;
384
385
var TOKEN_DOTDOT = 68 ;
386
+ var TOKEN_HEREDOC = 69 ;
385
387
var MAX_FUNC_ARGS = 20 ;
386
388
function isalpha ( c ) {
387
389
return viml_eqregh ( c , "^[A-Za-z]$" ) ;
@@ -580,6 +582,7 @@ function ExArg() {
580
582
// CURLYNAMEPART .value
581
583
// CURLYNAMEEXPR .value
582
584
// LAMBDA .rlist .left
585
+ // HEREDOC .rlist .op .str
583
586
function Node ( type ) {
584
587
return { "type" :type } ;
585
588
}
@@ -1770,6 +1773,49 @@ VimLParser.prototype.parse_cmd_call = function() {
1770
1773
this . add_node ( node ) ;
1771
1774
}
1772
1775
1776
+ VimLParser . prototype . parse_heredoc = function ( ) {
1777
+ var node = Node ( NODE_HEREDOC ) ;
1778
+ node . pos = this . ea . cmdpos ;
1779
+ node . op = "" ;
1780
+ node . rlist = [ ] ;
1781
+ node . str = "" ;
1782
+ var words = [ ] ;
1783
+ while ( TRUE ) {
1784
+ this . reader . skip_white ( ) ;
1785
+ var key = this . reader . read_alpha ( ) ;
1786
+ if ( key == "" ) {
1787
+ break ;
1788
+ }
1789
+ if ( key == "trim" ) {
1790
+ viml_add ( words , key ) ;
1791
+ }
1792
+ else {
1793
+ node . op = key ;
1794
+ }
1795
+ }
1796
+ if ( viml_empty ( words ) ) {
1797
+ this . reader . seek_set ( pos ) ;
1798
+ this . parse_cmd_common ( ) ;
1799
+ return ;
1800
+ }
1801
+ node . rlist = words ;
1802
+ var lines = [ ] ;
1803
+ this . parse_trail ( ) ;
1804
+ while ( TRUE ) {
1805
+ if ( this . reader . peek ( ) == "<EOF>" ) {
1806
+ break ;
1807
+ }
1808
+ var line = this . reader . getn ( - 1 ) ;
1809
+ if ( line == node . op ) {
1810
+ node . str = viml_join ( lines , "\n" ) + "\n" ;
1811
+ return node ;
1812
+ }
1813
+ viml_add ( lines , line ) ;
1814
+ this . reader . get ( ) ;
1815
+ }
1816
+ return NIL ;
1817
+ }
1818
+
1773
1819
VimLParser . prototype . parse_cmd_let = function ( ) {
1774
1820
var pos = this . reader . tell ( ) ;
1775
1821
this . reader . skip_white ( ) ;
@@ -1787,8 +1833,11 @@ VimLParser.prototype.parse_cmd_let = function() {
1787
1833
if ( s2 == ".." ) {
1788
1834
var s2 = this . reader . peekn ( 3 ) ;
1789
1835
}
1836
+ else if ( s2 == "=<" ) {
1837
+ var s2 = this . reader . peekn ( 3 ) ;
1838
+ }
1790
1839
// :let {var-name} ..
1791
- if ( this . ends_excmds ( s1 ) || s2 != "+=" && s2 != "-=" && s2 != ".=" && s2 != "..=" && s2 != "*=" && s2 != "/=" && s2 != "%=" && s1 != "=" ) {
1840
+ if ( this . ends_excmds ( s1 ) || s2 != "+=" && s2 != "-=" && s2 != ".=" && s2 != "..=" && s2 != "*=" && s2 != "/=" && s2 != "%=" && s2 != "=<<" && s1 != "=" ) {
1792
1841
this . reader . seek_set ( pos ) ;
1793
1842
this . parse_cmd_common ( ) ;
1794
1843
return ;
@@ -1806,6 +1855,14 @@ VimLParser.prototype.parse_cmd_let = function() {
1806
1855
this . reader . getn ( viml_len ( s2 ) ) ;
1807
1856
node . op = s2 ;
1808
1857
}
1858
+ else if ( s2 == "=<<" ) {
1859
+ this . reader . getn ( viml_len ( s2 ) ) ;
1860
+ this . reader . skip_white ( ) ;
1861
+ node . op = "=" ;
1862
+ node . right = this . parse_heredoc ( ) ;
1863
+ this . add_node ( node ) ;
1864
+ return ;
1865
+ }
1809
1866
else if ( s1 == "=" ) {
1810
1867
this . reader . getn ( 1 ) ;
1811
1868
node . op = s1 ;
@@ -4325,6 +4382,9 @@ Compiler.prototype.compile = function(node) {
4325
4382
else if ( node . type == NODE_LAMBDA ) {
4326
4383
return this . compile_lambda ( node ) ;
4327
4384
}
4385
+ else if ( node . type == NODE_HEREDOC ) {
4386
+ return this . compile_heredoc ( node ) ;
4387
+ }
4328
4388
else {
4329
4389
throw viml_printf ( "Compiler: unknown node: %s" , viml_string ( node ) ) ;
4330
4390
}
@@ -4808,6 +4868,18 @@ Compiler.prototype.compile_lambda = function(node) {
4808
4868
return viml_printf ( "(lambda (%s) %s)" , viml_join ( rlist , " " ) , this . compile ( node . left ) ) ;
4809
4869
}
4810
4870
4871
+ function escape_string ( str ) {
4872
+ var str = "\"" + viml_escape ( str , "\\\"" ) + "\"" ;
4873
+ var str = viml_substitute ( str , "\r" , "\\\\r" , "g" ) ;
4874
+ var str = viml_substitute ( str , "\n" , "\\\\n" , "g" ) ;
4875
+ var str = viml_substitute ( str , "\t" , "\\\\t" , "g" ) ;
4876
+ return str ;
4877
+ }
4878
+
4879
+ Compiler . prototype . compile_heredoc = function ( node ) {
4880
+ return viml_printf ( "(heredoc (%s) \"%s\" %s))" , viml_join ( node . rlist , " " ) , node . op , escape_string ( node . str ) ) ;
4881
+ }
4882
+
4811
4883
// TODO: under construction
4812
4884
function RegexpParser ( ) { this . __init__ . apply ( this , arguments ) ; }
4813
4885
RegexpParser . prototype . RE_VERY_NOMAGIC = 1 ;
0 commit comments