@@ -321,7 +321,8 @@ var NODE_LAMBDA = 92;
321
321
var NODE_BLOB = 93 ;
322
322
var NODE_CONST = 94 ;
323
323
var NODE_EVAL = 95 ;
324
- var NODE_METHOD = 96 ;
324
+ var NODE_HEREDOC = 96 ;
325
+ var NODE_METHOD = 97 ;
325
326
var TOKEN_EOF = 1 ;
326
327
var TOKEN_EOL = 2 ;
327
328
var TOKEN_SPACE = 3 ;
@@ -390,6 +391,7 @@ var TOKEN_ARROW = 65;
390
391
var TOKEN_BLOB = 66 ;
391
392
var TOKEN_LITCOPEN = 67 ;
392
393
var TOKEN_DOTDOT = 68 ;
394
+ var TOKEN_HEREDOC = 69 ;
393
395
var MAX_FUNC_ARGS = 20 ;
394
396
function isalpha ( c ) {
395
397
return viml_eqregh ( c , "^[A-Za-z]$" ) ;
@@ -592,6 +594,7 @@ function ExArg() {
592
594
// CURLYNAMEPART .value
593
595
// CURLYNAMEEXPR .value
594
596
// LAMBDA .rlist .left
597
+ // HEREDOC .rlist .op .body
595
598
function Node ( type ) {
596
599
return { "type" :type } ;
597
600
}
@@ -1797,6 +1800,44 @@ VimLParser.prototype.parse_cmd_call = function() {
1797
1800
this . add_node ( node ) ;
1798
1801
}
1799
1802
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
+
1800
1841
VimLParser . prototype . parse_cmd_let = function ( ) {
1801
1842
var pos = this . reader . tell ( ) ;
1802
1843
this . reader . skip_white ( ) ;
@@ -1814,8 +1855,11 @@ VimLParser.prototype.parse_cmd_let = function() {
1814
1855
if ( s2 == ".." ) {
1815
1856
var s2 = this . reader . peekn ( 3 ) ;
1816
1857
}
1858
+ else if ( s2 == "=<" ) {
1859
+ var s2 = this . reader . peekn ( 3 ) ;
1860
+ }
1817
1861
// :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 != "=" ) {
1819
1863
this . reader . seek_set ( pos ) ;
1820
1864
this . parse_cmd_common ( ) ;
1821
1865
return ;
@@ -1833,6 +1877,14 @@ VimLParser.prototype.parse_cmd_let = function() {
1833
1877
this . reader . getn ( viml_len ( s2 ) ) ;
1834
1878
node . op = s2 ;
1835
1879
}
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
+ }
1836
1888
else if ( s1 == "=" ) {
1837
1889
this . reader . getn ( 1 ) ;
1838
1890
node . op = s1 ;
@@ -4481,6 +4533,9 @@ Compiler.prototype.compile = function(node) {
4481
4533
else if ( node . type == NODE_LAMBDA ) {
4482
4534
return this . compile_lambda ( node ) ;
4483
4535
}
4536
+ else if ( node . type == NODE_HEREDOC ) {
4537
+ return this . compile_heredoc ( node ) ;
4538
+ }
4484
4539
else {
4485
4540
throw viml_printf ( "Compiler: unknown node: %s" , viml_string ( node ) ) ;
4486
4541
}
@@ -4997,11 +5052,46 @@ Compiler.prototype.compile_curlynameexpr = function(node) {
4997
5052
return "{" + this . compile ( node . value ) + "}" ;
4998
5053
}
4999
5054
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
+
5000
5073
Compiler . prototype . compile_lambda = function ( node ) {
5001
5074
var rlist = node . rlist . map ( ( function ( vval ) { return this . compile ( vval ) ; } ) . bind ( this ) ) ;
5002
5075
return viml_printf ( "(lambda (%s) %s)" , viml_join ( rlist , " " ) , this . compile ( node . left ) ) ;
5003
5076
}
5004
5077
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
+
5005
5095
// TODO: under construction
5006
5096
function RegexpParser ( ) { this . __init__ . apply ( this , arguments ) ; }
5007
5097
RegexpParser . prototype . RE_VERY_NOMAGIC = 1 ;
@@ -5682,9 +5772,9 @@ RegexpParser.prototype.get_token_sq_char_class = function() {
5682
5772
var r = this . reader . read_alpha ( ) ;
5683
5773
if ( this . reader . p ( 0 ) == ":" && this . reader . p ( 1 ) == "]" ) {
5684
5774
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 ] ;
5688
5778
if ( r == name ) {
5689
5779
return "[:" + name + ":]" ;
5690
5780
}
@@ -5817,9 +5907,9 @@ RegexpParser.prototype.getoctchrs = function() {
5817
5907
5818
5908
RegexpParser . prototype . gethexchrs = function ( n ) {
5819
5909
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 ] ;
5823
5913
var c = this . reader . peek ( ) ;
5824
5914
if ( ! isxdigit ( c ) ) {
5825
5915
break ;
0 commit comments