@@ -488,6 +488,7 @@ function ExArg() {
488488// node rest
489489// node[] list
490490// node[] rlist
491+ // node[] default_args
491492// node[] body
492493// string op
493494// string str
@@ -497,7 +498,7 @@ function ExArg() {
497498// TOPLEVEL .body
498499// COMMENT .str
499500// EXCMD .ea .str
500- // FUNCTION .ea .body .left .rlist .attr .endfunction
501+ // FUNCTION .ea .body .left .rlist .default_args . attr .endfunction
501502// ENDFUNCTION .ea
502503// DELFUNCTION .ea .left
503504// RETURN .ea .left
@@ -1639,6 +1640,7 @@ VimLParser.prototype.parse_cmd_function = function() {
16391640 node . ea = this . ea ;
16401641 node . left = left ;
16411642 node . rlist = [ ] ;
1643+ node . default_args = [ ] ;
16421644 node . attr = { "range" :0 , "abort" :0 , "dict" :0 , "closure" :0 } ;
16431645 node . endfunction = NIL ;
16441646 this . reader . getn ( 1 ) ;
@@ -1662,6 +1664,13 @@ VimLParser.prototype.parse_cmd_function = function() {
16621664 varnode . pos = token . pos ;
16631665 varnode . value = token . value ;
16641666 viml_add ( node . rlist , varnode ) ;
1667+ if ( tokenizer . peek ( ) . type == TOKEN_EQ ) {
1668+ tokenizer . get ( ) ;
1669+ viml_add ( node . default_args , this . parse_expr ( ) ) ;
1670+ }
1671+ else if ( viml_len ( node . default_args ) > 0 ) {
1672+ throw Err ( "E989: Non-default argument follows default argument" , varnode . pos ) ;
1673+ }
16651674 // XXX: Vim doesn't skip white space before comma. F(a ,b) => E475
16661675 if ( iswhite ( this . reader . p ( 0 ) ) && tokenizer . peek ( ) . type == TOKEN_COMMA ) {
16671676 throw Err ( "E475: Invalid argument: White space is not allowed before comma" , this . reader . getpos ( ) ) ;
@@ -4465,15 +4474,28 @@ Compiler.prototype.compile_excmd = function(node) {
44654474Compiler . prototype . compile_function = function ( node ) {
44664475 var left = this . compile ( node . left ) ;
44674476 var rlist = node . rlist . map ( ( function ( vval ) { return this . compile ( vval ) ; } ) . bind ( this ) ) ;
4468- if ( ! viml_empty ( rlist ) && rlist [ rlist . length - 1 ] == "..." ) {
4469- rlist [ rlist . length - 1 ] = ". ..." ;
4470- }
4471- if ( viml_empty ( rlist ) ) {
4472- this . out ( "(function (%s)" , left ) ;
4473- }
4474- else {
4475- this . out ( "(function (%s %s)" , left , viml_join ( rlist , " " ) ) ;
4477+ var default_args = node . default_args . map ( ( function ( vval ) { return this . compile ( vval ) ; } ) . bind ( this ) ) ;
4478+ if ( ! viml_empty ( rlist ) ) {
4479+ var remaining = FALSE ;
4480+ if ( rlist [ rlist . length - 1 ] == "..." ) {
4481+ viml_remove ( rlist , - 1 ) ;
4482+ var remaining = TRUE ;
4483+ }
4484+ var __c11 = viml_range ( viml_len ( rlist ) ) ;
4485+ for ( var __i11 = 0 ; __i11 < __c11 . length ; ++ __i11 ) {
4486+ var i = __c11 [ __i11 ] ;
4487+ if ( i < viml_len ( rlist ) - viml_len ( default_args ) ) {
4488+ left += viml_printf ( " %s" , rlist [ i ] ) ;
4489+ }
4490+ else {
4491+ left += viml_printf ( " (%s %s)" , rlist [ i ] , default_args [ i + viml_len ( default_args ) - viml_len ( rlist ) ] ) ;
4492+ }
4493+ }
4494+ if ( remaining ) {
4495+ left += " . ..." ;
4496+ }
44764497 }
4498+ this . out ( "(function (%s)" , left ) ;
44774499 this . incindent ( " " ) ;
44784500 this . compile_body ( node . body ) ;
44794501 this . out ( ")" ) ;
@@ -4560,9 +4582,9 @@ Compiler.prototype.compile_if = function(node) {
45604582 this . incindent ( " " ) ;
45614583 this . compile_body ( node . body ) ;
45624584 this . decindent ( ) ;
4563- var __c11 = node . elseif ;
4564- for ( var __i11 = 0 ; __i11 < __c11 . length ; ++ __i11 ) {
4565- var enode = __c11 [ __i11 ] ;
4585+ var __c12 = node . elseif ;
4586+ for ( var __i12 = 0 ; __i12 < __c12 . length ; ++ __i12 ) {
4587+ var enode = __c12 [ __i12 ] ;
45664588 this . out ( " elseif %s" , this . compile ( enode . cond ) ) ;
45674589 this . incindent ( " " ) ;
45684590 this . compile_body ( enode . body ) ;
@@ -4619,9 +4641,9 @@ Compiler.prototype.compile_try = function(node) {
46194641 this . out ( "(try" ) ;
46204642 this . incindent ( " " ) ;
46214643 this . compile_body ( node . body ) ;
4622- var __c12 = node . catch ;
4623- for ( var __i12 = 0 ; __i12 < __c12 . length ; ++ __i12 ) {
4624- var cnode = __c12 [ __i12 ] ;
4644+ var __c13 = node . catch ;
4645+ for ( var __i13 = 0 ; __i13 < __c13 . length ; ++ __i13 ) {
4646+ var cnode = __c13 [ __i13 ] ;
46254647 if ( cnode . pattern !== NIL ) {
46264648 this . decindent ( ) ;
46274649 this . out ( " catch /%s/" , cnode . pattern ) ;
@@ -5615,9 +5637,9 @@ RegexpParser.prototype.get_token_sq_char_class = function() {
56155637 var r = this . reader . read_alpha ( ) ;
56165638 if ( this . reader . p ( 0 ) == ":" && this . reader . p ( 1 ) == "]" ) {
56175639 this . reader . seek_cur ( 2 ) ;
5618- var __c13 = class_names ;
5619- for ( var __i13 = 0 ; __i13 < __c13 . length ; ++ __i13 ) {
5620- var name = __c13 [ __i13 ] ;
5640+ var __c14 = class_names ;
5641+ for ( var __i14 = 0 ; __i14 < __c14 . length ; ++ __i14 ) {
5642+ var name = __c14 [ __i14 ] ;
56215643 if ( r == name ) {
56225644 return "[:" + name + ":]" ;
56235645 }
@@ -5750,9 +5772,9 @@ RegexpParser.prototype.getoctchrs = function() {
57505772
57515773RegexpParser . prototype . gethexchrs = function ( n ) {
57525774 var r = "" ;
5753- var __c14 = viml_range ( n ) ;
5754- for ( var __i14 = 0 ; __i14 < __c14 . length ; ++ __i14 ) {
5755- var i = __c14 [ __i14 ] ;
5775+ var __c15 = viml_range ( n ) ;
5776+ for ( var __i15 = 0 ; __i15 < __c15 . length ; ++ __i15 ) {
5777+ var i = __c15 [ __i15 ] ;
57565778 var c = this . reader . peek ( ) ;
57575779 if ( ! isxdigit ( c ) ) {
57585780 break ;
0 commit comments