@@ -321,6 +321,7 @@ var NODE_LAMBDA = 92;
321321var NODE_BLOB = 93 ;
322322var NODE_CONST = 94 ;
323323var NODE_EVAL = 95 ;
324+ var NODE_HEREDOC = 96 ;
324325var TOKEN_EOF = 1 ;
325326var TOKEN_EOL = 2 ;
326327var TOKEN_SPACE = 3 ;
@@ -389,6 +390,7 @@ var TOKEN_ARROW = 65;
389390var TOKEN_BLOB = 66 ;
390391var TOKEN_LITCOPEN = 67 ;
391392var TOKEN_DOTDOT = 68 ;
393+ var TOKEN_HEREDOC = 69 ;
392394var MAX_FUNC_ARGS = 20 ;
393395function isalpha ( c ) {
394396 return viml_eqregh ( c , "^[A-Za-z]$" ) ;
@@ -590,6 +592,7 @@ function ExArg() {
590592// CURLYNAMEPART .value
591593// CURLYNAMEEXPR .value
592594// LAMBDA .rlist .left
595+ // HEREDOC .rlist .op .body
593596function Node ( type ) {
594597 return { "type" :type } ;
595598}
@@ -1795,6 +1798,44 @@ VimLParser.prototype.parse_cmd_call = function() {
17951798 this . add_node ( node ) ;
17961799}
17971800
1801+ VimLParser . prototype . parse_heredoc = function ( ) {
1802+ var node = Node ( NODE_HEREDOC ) ;
1803+ node . pos = this . ea . cmdpos ;
1804+ node . op = "" ;
1805+ node . rlist = [ ] ;
1806+ node . body = [ ] ;
1807+ while ( TRUE ) {
1808+ this . reader . skip_white ( ) ;
1809+ var key = this . reader . read_word ( ) ;
1810+ if ( key == "" ) {
1811+ break ;
1812+ }
1813+ if ( ! islower ( key [ 0 ] ) ) {
1814+ node . op = key ;
1815+ break ;
1816+ }
1817+ else {
1818+ viml_add ( node . rlist , key ) ;
1819+ }
1820+ }
1821+ if ( node . op == "" ) {
1822+ throw Err ( "E172: Missing marker" , this . reader . getpos ( ) ) ;
1823+ }
1824+ this . parse_trail ( ) ;
1825+ while ( TRUE ) {
1826+ if ( this . reader . peek ( ) == "<EOF>" ) {
1827+ break ;
1828+ }
1829+ var line = this . reader . getn ( - 1 ) ;
1830+ if ( line == node . op ) {
1831+ return node ;
1832+ }
1833+ viml_add ( node . body , line ) ;
1834+ this . reader . get ( ) ;
1835+ }
1836+ throw Err ( viml_printf ( "E990: Missing end marker '%s'" , node . op ) , this . reader . getpos ( ) ) ;
1837+ }
1838+
17981839VimLParser . prototype . parse_cmd_let = function ( ) {
17991840 var pos = this . reader . tell ( ) ;
18001841 this . reader . skip_white ( ) ;
@@ -1812,8 +1853,11 @@ VimLParser.prototype.parse_cmd_let = function() {
18121853 if ( s2 == ".." ) {
18131854 var s2 = this . reader . peekn ( 3 ) ;
18141855 }
1856+ else if ( s2 == "=<" ) {
1857+ var s2 = this . reader . peekn ( 3 ) ;
1858+ }
18151859 // :let {var-name} ..
1816- if ( this . ends_excmds ( s1 ) || s2 != "+=" && s2 != "-=" && s2 != ".=" && s2 != "..=" && s2 != "*=" && s2 != "/=" && s2 != "%=" && s1 != "=" ) {
1860+ if ( this . ends_excmds ( s1 ) || s2 != "+=" && s2 != "-=" && s2 != ".=" && s2 != "..=" && s2 != "*=" && s2 != "/=" && s2 != "%=" && s2 != "=<<" && s1 != "=" ) {
18171861 this . reader . seek_set ( pos ) ;
18181862 this . parse_cmd_common ( ) ;
18191863 return ;
@@ -1831,6 +1875,14 @@ VimLParser.prototype.parse_cmd_let = function() {
18311875 this . reader . getn ( viml_len ( s2 ) ) ;
18321876 node . op = s2 ;
18331877 }
1878+ else if ( s2 == "=<<" ) {
1879+ this . reader . getn ( viml_len ( s2 ) ) ;
1880+ this . reader . skip_white ( ) ;
1881+ node . op = s2 ;
1882+ node . right = this . parse_heredoc ( ) ;
1883+ this . add_node ( node ) ;
1884+ return ;
1885+ }
18341886 else if ( s1 == "=" ) {
18351887 this . reader . getn ( 1 ) ;
18361888 node . op = s1 ;
@@ -4461,6 +4513,9 @@ Compiler.prototype.compile = function(node) {
44614513 else if ( node . type == NODE_LAMBDA ) {
44624514 return this . compile_lambda ( node ) ;
44634515 }
4516+ else if ( node . type == NODE_HEREDOC ) {
4517+ return this . compile_heredoc ( node ) ;
4518+ }
44644519 else {
44654520 throw viml_printf ( "Compiler: unknown node: %s" , viml_string ( node ) ) ;
44664521 }
@@ -4973,11 +5028,46 @@ Compiler.prototype.compile_curlynameexpr = function(node) {
49735028 return "{" + this . compile ( node . value ) + "}" ;
49745029}
49755030
5031+ Compiler . prototype . escape_string = function ( str ) {
5032+ var m = { "\n" :"\\n" , "\t" :"\\t" , "\r" :"\\r" } ;
5033+ var out = "\"" ;
5034+ var __c14 = viml_range ( viml_len ( str ) ) ;
5035+ for ( var __i14 = 0 ; __i14 < __c14 . length ; ++ __i14 ) {
5036+ var i = __c14 [ __i14 ] ;
5037+ var c = str [ i ] ;
5038+ if ( viml_has_key ( m , c ) ) {
5039+ out += m [ c ] ;
5040+ }
5041+ else {
5042+ out += c ;
5043+ }
5044+ }
5045+ out += "\"" ;
5046+ return out ;
5047+ }
5048+
49765049Compiler . prototype . compile_lambda = function ( node ) {
49775050 var rlist = node . rlist . map ( ( function ( vval ) { return this . compile ( vval ) ; } ) . bind ( this ) ) ;
49785051 return viml_printf ( "(lambda (%s) %s)" , viml_join ( rlist , " " ) , this . compile ( node . left ) ) ;
49795052}
49805053
5054+ Compiler . prototype . compile_heredoc = function ( node ) {
5055+ if ( viml_empty ( node . rlist ) ) {
5056+ var rlist = "(list)" ;
5057+ }
5058+ else {
5059+ var rlist = "(list " + viml_join ( node . rlist . map ( ( function ( vval ) { return this . escape_string ( vval ) ; } ) . bind ( this ) ) , " " ) + ")" ;
5060+ }
5061+ if ( viml_empty ( node . body ) ) {
5062+ var body = "(list)" ;
5063+ }
5064+ else {
5065+ var body = "(list " + viml_join ( node . body . map ( ( function ( vval ) { return this . escape_string ( vval ) ; } ) . bind ( this ) ) , " " ) + ")" ;
5066+ }
5067+ var op = this . escape_string ( node . op ) ;
5068+ return viml_printf ( "(heredoc %s %s %s)" , rlist , op , body ) ;
5069+ }
5070+
49815071// TODO: under construction
49825072function RegexpParser ( ) { this . __init__ . apply ( this , arguments ) ; }
49835073RegexpParser . prototype . RE_VERY_NOMAGIC = 1 ;
@@ -5658,9 +5748,9 @@ RegexpParser.prototype.get_token_sq_char_class = function() {
56585748 var r = this . reader . read_alpha ( ) ;
56595749 if ( this . reader . p ( 0 ) == ":" && this . reader . p ( 1 ) == "]" ) {
56605750 this . reader . seek_cur ( 2 ) ;
5661- var __c14 = class_names ;
5662- for ( var __i14 = 0 ; __i14 < __c14 . length ; ++ __i14 ) {
5663- var name = __c14 [ __i14 ] ;
5751+ var __c15 = class_names ;
5752+ for ( var __i15 = 0 ; __i15 < __c15 . length ; ++ __i15 ) {
5753+ var name = __c15 [ __i15 ] ;
56645754 if ( r == name ) {
56655755 return "[:" + name + ":]" ;
56665756 }
@@ -5793,9 +5883,9 @@ RegexpParser.prototype.getoctchrs = function() {
57935883
57945884RegexpParser . prototype . gethexchrs = function ( n ) {
57955885 var r = "" ;
5796- var __c15 = viml_range ( n ) ;
5797- for ( var __i15 = 0 ; __i15 < __c15 . length ; ++ __i15 ) {
5798- var i = __c15 [ __i15 ] ;
5886+ var __c16 = viml_range ( n ) ;
5887+ for ( var __i16 = 0 ; __i16 < __c16 . length ; ++ __i16 ) {
5888+ var i = __c16 [ __i16 ] ;
57995889 var c = this . reader . peek ( ) ;
58005890 if ( ! isxdigit ( c ) ) {
58015891 break ;
0 commit comments