@@ -321,6 +321,7 @@ 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_HEREDOC = 96 ;
324
325
var TOKEN_EOF = 1 ;
325
326
var TOKEN_EOL = 2 ;
326
327
var TOKEN_SPACE = 3 ;
@@ -389,6 +390,7 @@ var TOKEN_ARROW = 65;
389
390
var TOKEN_BLOB = 66 ;
390
391
var TOKEN_LITCOPEN = 67 ;
391
392
var TOKEN_DOTDOT = 68 ;
393
+ var TOKEN_HEREDOC = 69 ;
392
394
var MAX_FUNC_ARGS = 20 ;
393
395
function isalpha ( c ) {
394
396
return viml_eqregh ( c , "^[A-Za-z]$" ) ;
@@ -590,6 +592,7 @@ function ExArg() {
590
592
// CURLYNAMEPART .value
591
593
// CURLYNAMEEXPR .value
592
594
// LAMBDA .rlist .left
595
+ // HEREDOC .rlist .op .body
593
596
function Node ( type ) {
594
597
return { "type" :type } ;
595
598
}
@@ -1795,6 +1798,44 @@ VimLParser.prototype.parse_cmd_call = function() {
1795
1798
this . add_node ( node ) ;
1796
1799
}
1797
1800
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
+
1798
1839
VimLParser . prototype . parse_cmd_let = function ( ) {
1799
1840
var pos = this . reader . tell ( ) ;
1800
1841
this . reader . skip_white ( ) ;
@@ -1812,8 +1853,11 @@ VimLParser.prototype.parse_cmd_let = function() {
1812
1853
if ( s2 == ".." ) {
1813
1854
var s2 = this . reader . peekn ( 3 ) ;
1814
1855
}
1856
+ else if ( s2 == "=<" ) {
1857
+ var s2 = this . reader . peekn ( 3 ) ;
1858
+ }
1815
1859
// :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 != "=" ) {
1817
1861
this . reader . seek_set ( pos ) ;
1818
1862
this . parse_cmd_common ( ) ;
1819
1863
return ;
@@ -1831,6 +1875,14 @@ VimLParser.prototype.parse_cmd_let = function() {
1831
1875
this . reader . getn ( viml_len ( s2 ) ) ;
1832
1876
node . op = s2 ;
1833
1877
}
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
+ }
1834
1886
else if ( s1 == "=" ) {
1835
1887
this . reader . getn ( 1 ) ;
1836
1888
node . op = s1 ;
@@ -4461,6 +4513,9 @@ Compiler.prototype.compile = function(node) {
4461
4513
else if ( node . type == NODE_LAMBDA ) {
4462
4514
return this . compile_lambda ( node ) ;
4463
4515
}
4516
+ else if ( node . type == NODE_HEREDOC ) {
4517
+ return this . compile_heredoc ( node ) ;
4518
+ }
4464
4519
else {
4465
4520
throw viml_printf ( "Compiler: unknown node: %s" , viml_string ( node ) ) ;
4466
4521
}
@@ -4973,11 +5028,46 @@ Compiler.prototype.compile_curlynameexpr = function(node) {
4973
5028
return "{" + this . compile ( node . value ) + "}" ;
4974
5029
}
4975
5030
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
+
4976
5049
Compiler . prototype . compile_lambda = function ( node ) {
4977
5050
var rlist = node . rlist . map ( ( function ( vval ) { return this . compile ( vval ) ; } ) . bind ( this ) ) ;
4978
5051
return viml_printf ( "(lambda (%s) %s)" , viml_join ( rlist , " " ) , this . compile ( node . left ) ) ;
4979
5052
}
4980
5053
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
+
4981
5071
// TODO: under construction
4982
5072
function RegexpParser ( ) { this . __init__ . apply ( this , arguments ) ; }
4983
5073
RegexpParser . prototype . RE_VERY_NOMAGIC = 1 ;
@@ -5658,9 +5748,9 @@ RegexpParser.prototype.get_token_sq_char_class = function() {
5658
5748
var r = this . reader . read_alpha ( ) ;
5659
5749
if ( this . reader . p ( 0 ) == ":" && this . reader . p ( 1 ) == "]" ) {
5660
5750
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 ] ;
5664
5754
if ( r == name ) {
5665
5755
return "[:" + name + ":]" ;
5666
5756
}
@@ -5793,9 +5883,9 @@ RegexpParser.prototype.getoctchrs = function() {
5793
5883
5794
5884
RegexpParser . prototype . gethexchrs = function ( n ) {
5795
5885
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 ] ;
5799
5889
var c = this . reader . peek ( ) ;
5800
5890
if ( ! isxdigit ( c ) ) {
5801
5891
break ;
0 commit comments