@@ -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,14 +4474,18 @@ 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 ) ) ;
4477+ var default_args = node . default_args . map ( ( function ( vval ) { return this . compile ( vval ) ; } ) . bind ( this ) ) ;
44684478 if ( ! viml_empty ( rlist ) && rlist [ rlist . length - 1 ] == "..." ) {
44694479 rlist [ rlist . length - 1 ] = ". ..." ;
44704480 }
44714481 if ( viml_empty ( rlist ) ) {
44724482 this . out ( "(function (%s)" , left ) ;
44734483 }
4484+ else if ( viml_empty ( default_args ) ) {
4485+ this . out ( "(function (%s) (%s)" , left , viml_join ( rlist , " " ) ) ;
4486+ }
44744487 else {
4475- this . out ( "(function (%s %s)" , left , viml_join ( rlist , " " ) ) ;
4488+ this . out ( "(function (%s) ( %s) (%s) " , left , viml_join ( rlist , " " ) , viml_join ( default_args , " " ) ) ;
44764489 }
44774490 this . incindent ( " " ) ;
44784491 this . compile_body ( node . body ) ;
0 commit comments