@@ -314,6 +314,7 @@ var NODE_CURLYNAMEPART = 90;
314314var NODE_CURLYNAMEEXPR = 91 ;
315315var NODE_LAMBDA = 92 ;
316316var NODE_BLOB = 93 ;
317+ var NODE_HEREDOC = 94 ;
317318var TOKEN_EOF = 1 ;
318319var TOKEN_EOL = 2 ;
319320var TOKEN_SPACE = 3 ;
@@ -382,6 +383,7 @@ var TOKEN_ARROW = 65;
382383var TOKEN_BLOB = 66 ;
383384var TOKEN_LITCOPEN = 67 ;
384385var TOKEN_DOTDOT = 68 ;
386+ var TOKEN_HEREDOC = 69 ;
385387var MAX_FUNC_ARGS = 20 ;
386388function isalpha ( c ) {
387389 return viml_eqregh ( c , "^[A-Za-z]$" ) ;
@@ -580,6 +582,7 @@ function ExArg() {
580582// CURLYNAMEPART .value
581583// CURLYNAMEEXPR .value
582584// LAMBDA .rlist .left
585+ // HEREDOC .rlist .op .str
583586function Node ( type ) {
584587 return { "type" :type } ;
585588}
@@ -1770,6 +1773,49 @@ VimLParser.prototype.parse_cmd_call = function() {
17701773 this . add_node ( node ) ;
17711774}
17721775
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+
17731819VimLParser . prototype . parse_cmd_let = function ( ) {
17741820 var pos = this . reader . tell ( ) ;
17751821 this . reader . skip_white ( ) ;
@@ -1787,8 +1833,11 @@ VimLParser.prototype.parse_cmd_let = function() {
17871833 if ( s2 == ".." ) {
17881834 var s2 = this . reader . peekn ( 3 ) ;
17891835 }
1836+ else if ( s2 == "=<" ) {
1837+ var s2 = this . reader . peekn ( 3 ) ;
1838+ }
17901839 // :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 != "=" ) {
17921841 this . reader . seek_set ( pos ) ;
17931842 this . parse_cmd_common ( ) ;
17941843 return ;
@@ -1806,6 +1855,14 @@ VimLParser.prototype.parse_cmd_let = function() {
18061855 this . reader . getn ( viml_len ( s2 ) ) ;
18071856 node . op = s2 ;
18081857 }
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+ }
18091866 else if ( s1 == "=" ) {
18101867 this . reader . getn ( 1 ) ;
18111868 node . op = s1 ;
@@ -4325,6 +4382,9 @@ Compiler.prototype.compile = function(node) {
43254382 else if ( node . type == NODE_LAMBDA ) {
43264383 return this . compile_lambda ( node ) ;
43274384 }
4385+ else if ( node . type == NODE_HEREDOC ) {
4386+ return this . compile_heredoc ( node ) ;
4387+ }
43284388 else {
43294389 throw viml_printf ( "Compiler: unknown node: %s" , viml_string ( node ) ) ;
43304390 }
@@ -4808,6 +4868,18 @@ Compiler.prototype.compile_lambda = function(node) {
48084868 return viml_printf ( "(lambda (%s) %s)" , viml_join ( rlist , " " ) , this . compile ( node . left ) ) ;
48094869}
48104870
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+
48114883// TODO: under construction
48124884function RegexpParser ( ) { this . __init__ . apply ( this , arguments ) ; }
48134885RegexpParser . prototype . RE_VERY_NOMAGIC = 1 ;
0 commit comments