@@ -321,7 +321,8 @@ var NODE_LAMBDA = 92;
321321var NODE_BLOB = 93 ;
322322var NODE_CONST = 94 ;
323323var NODE_EVAL = 95 ;
324- var NODE_METHOD = 96 ;
324+ var NODE_HEREDOC = 96 ;
325+ var NODE_METHOD = 97 ;
325326var TOKEN_EOF = 1 ;
326327var TOKEN_EOL = 2 ;
327328var TOKEN_SPACE = 3 ;
@@ -390,6 +391,7 @@ var TOKEN_ARROW = 65;
390391var TOKEN_BLOB = 66 ;
391392var TOKEN_LITCOPEN = 67 ;
392393var TOKEN_DOTDOT = 68 ;
394+ var TOKEN_HEREDOC = 69 ;
393395var MAX_FUNC_ARGS = 20 ;
394396function isalpha ( c ) {
395397 return viml_eqregh ( c , "^[A-Za-z]$" ) ;
@@ -592,6 +594,7 @@ function ExArg() {
592594// CURLYNAMEPART .value
593595// CURLYNAMEEXPR .value
594596// LAMBDA .rlist .left
597+ // HEREDOC .rlist .op .body
595598function Node ( type ) {
596599 return { "type" :type } ;
597600}
@@ -1797,6 +1800,44 @@ VimLParser.prototype.parse_cmd_call = function() {
17971800 this . add_node ( node ) ;
17981801}
17991802
1803+ VimLParser . prototype . parse_heredoc = function ( ) {
1804+ var node = Node ( NODE_HEREDOC ) ;
1805+ node . pos = this . ea . cmdpos ;
1806+ node . op = "" ;
1807+ node . rlist = [ ] ;
1808+ node . body = [ ] ;
1809+ while ( TRUE ) {
1810+ this . reader . skip_white ( ) ;
1811+ var key = this . reader . read_word ( ) ;
1812+ if ( key == "" ) {
1813+ break ;
1814+ }
1815+ if ( ! islower ( key [ 0 ] ) ) {
1816+ node . op = key ;
1817+ break ;
1818+ }
1819+ else {
1820+ viml_add ( node . rlist , key ) ;
1821+ }
1822+ }
1823+ if ( node . op == "" ) {
1824+ throw Err ( "E172: Missing marker" , this . reader . getpos ( ) ) ;
1825+ }
1826+ this . parse_trail ( ) ;
1827+ while ( TRUE ) {
1828+ if ( this . reader . peek ( ) == "<EOF>" ) {
1829+ break ;
1830+ }
1831+ var line = this . reader . getn ( - 1 ) ;
1832+ if ( line == node . op ) {
1833+ return node ;
1834+ }
1835+ viml_add ( node . body , line ) ;
1836+ this . reader . get ( ) ;
1837+ }
1838+ throw Err ( viml_printf ( "E990: Missing end marker '%s'" , node . op ) , this . reader . getpos ( ) ) ;
1839+ }
1840+
18001841VimLParser . prototype . parse_cmd_let = function ( ) {
18011842 var pos = this . reader . tell ( ) ;
18021843 this . reader . skip_white ( ) ;
@@ -1814,8 +1855,11 @@ VimLParser.prototype.parse_cmd_let = function() {
18141855 if ( s2 == ".." ) {
18151856 var s2 = this . reader . peekn ( 3 ) ;
18161857 }
1858+ else if ( s2 == "=<" ) {
1859+ var s2 = this . reader . peekn ( 3 ) ;
1860+ }
18171861 // :let {var-name} ..
1818- if ( this . ends_excmds ( s1 ) || s2 != "+=" && s2 != "-=" && s2 != ".=" && s2 != "..=" && s2 != "*=" && s2 != "/=" && s2 != "%=" && s1 != "=" ) {
1862+ if ( this . ends_excmds ( s1 ) || s2 != "+=" && s2 != "-=" && s2 != ".=" && s2 != "..=" && s2 != "*=" && s2 != "/=" && s2 != "%=" && s2 != "=<<" && s1 != "=" ) {
18191863 this . reader . seek_set ( pos ) ;
18201864 this . parse_cmd_common ( ) ;
18211865 return ;
@@ -1833,6 +1877,14 @@ VimLParser.prototype.parse_cmd_let = function() {
18331877 this . reader . getn ( viml_len ( s2 ) ) ;
18341878 node . op = s2 ;
18351879 }
1880+ else if ( s2 == "=<<" ) {
1881+ this . reader . getn ( viml_len ( s2 ) ) ;
1882+ this . reader . skip_white ( ) ;
1883+ node . op = s2 ;
1884+ node . right = this . parse_heredoc ( ) ;
1885+ this . add_node ( node ) ;
1886+ return ;
1887+ }
18361888 else if ( s1 == "=" ) {
18371889 this . reader . getn ( 1 ) ;
18381890 node . op = s1 ;
@@ -4481,6 +4533,9 @@ Compiler.prototype.compile = function(node) {
44814533 else if ( node . type == NODE_LAMBDA ) {
44824534 return this . compile_lambda ( node ) ;
44834535 }
4536+ else if ( node . type == NODE_HEREDOC ) {
4537+ return this . compile_heredoc ( node ) ;
4538+ }
44844539 else {
44854540 throw viml_printf ( "Compiler: unknown node: %s" , viml_string ( node ) ) ;
44864541 }
@@ -4997,11 +5052,46 @@ Compiler.prototype.compile_curlynameexpr = function(node) {
49975052 return "{" + this . compile ( node . value ) + "}" ;
49985053}
49995054
5055+ Compiler . prototype . escape_string = function ( str ) {
5056+ var m = { "\n" :"\\n" , "\t" :"\\t" , "\r" :"\\r" } ;
5057+ var out = "\"" ;
5058+ var __c14 = viml_range ( viml_len ( str ) ) ;
5059+ for ( var __i14 = 0 ; __i14 < __c14 . length ; ++ __i14 ) {
5060+ var i = __c14 [ __i14 ] ;
5061+ var c = str [ i ] ;
5062+ if ( viml_has_key ( m , c ) ) {
5063+ out += m [ c ] ;
5064+ }
5065+ else {
5066+ out += c ;
5067+ }
5068+ }
5069+ out += "\"" ;
5070+ return out ;
5071+ }
5072+
50005073Compiler . prototype . compile_lambda = function ( node ) {
50015074 var rlist = node . rlist . map ( ( function ( vval ) { return this . compile ( vval ) ; } ) . bind ( this ) ) ;
50025075 return viml_printf ( "(lambda (%s) %s)" , viml_join ( rlist , " " ) , this . compile ( node . left ) ) ;
50035076}
50045077
5078+ Compiler . prototype . compile_heredoc = function ( node ) {
5079+ if ( viml_empty ( node . rlist ) ) {
5080+ var rlist = "(list)" ;
5081+ }
5082+ else {
5083+ var rlist = "(list " + viml_join ( node . rlist . map ( ( function ( vval ) { return this . escape_string ( vval ) ; } ) . bind ( this ) ) , " " ) + ")" ;
5084+ }
5085+ if ( viml_empty ( node . body ) ) {
5086+ var body = "(list)" ;
5087+ }
5088+ else {
5089+ var body = "(list " + viml_join ( node . body . map ( ( function ( vval ) { return this . escape_string ( vval ) ; } ) . bind ( this ) ) , " " ) + ")" ;
5090+ }
5091+ var op = this . escape_string ( node . op ) ;
5092+ return viml_printf ( "(heredoc %s %s %s)" , rlist , op , body ) ;
5093+ }
5094+
50055095// TODO: under construction
50065096function RegexpParser ( ) { this . __init__ . apply ( this , arguments ) ; }
50075097RegexpParser . prototype . RE_VERY_NOMAGIC = 1 ;
@@ -5682,9 +5772,9 @@ RegexpParser.prototype.get_token_sq_char_class = function() {
56825772 var r = this . reader . read_alpha ( ) ;
56835773 if ( this . reader . p ( 0 ) == ":" && this . reader . p ( 1 ) == "]" ) {
56845774 this . reader . seek_cur ( 2 ) ;
5685- var __c14 = class_names ;
5686- for ( var __i14 = 0 ; __i14 < __c14 . length ; ++ __i14 ) {
5687- var name = __c14 [ __i14 ] ;
5775+ var __c15 = class_names ;
5776+ for ( var __i15 = 0 ; __i15 < __c15 . length ; ++ __i15 ) {
5777+ var name = __c15 [ __i15 ] ;
56885778 if ( r == name ) {
56895779 return "[:" + name + ":]" ;
56905780 }
@@ -5817,9 +5907,9 @@ RegexpParser.prototype.getoctchrs = function() {
58175907
58185908RegexpParser . prototype . gethexchrs = function ( n ) {
58195909 var r = "" ;
5820- var __c15 = viml_range ( n ) ;
5821- for ( var __i15 = 0 ; __i15 < __c15 . length ; ++ __i15 ) {
5822- var i = __c15 [ __i15 ] ;
5910+ var __c16 = viml_range ( n ) ;
5911+ for ( var __i16 = 0 ; __i16 < __c16 . length ; ++ __i16 ) {
5912+ var i = __c16 [ __i16 ] ;
58235913 var c = this . reader . peek ( ) ;
58245914 if ( ! isxdigit ( c ) ) {
58255915 break ;
0 commit comments