@@ -139,7 +139,8 @@ let s:NODE_CURLYNAMEEXPR = 91
139
139
let s: NODE_LAMBDA = 92
140
140
let s: NODE_BLOB = 93
141
141
let s: NODE_CONST = 94
142
- let s: NODE_METHOD = 95
142
+ let s: NODE_EVAL = 95
143
+ let s: NODE_METHOD = 96
143
144
144
145
let s: TOKEN_EOF = 1
145
146
let s: TOKEN_EOL = 2
@@ -311,6 +312,7 @@ endfunction
311
312
" node rest
312
313
" node[] list
313
314
" node[] rlist
315
+ " node[] default_args
314
316
" node[] body
315
317
" string op
316
318
" string str
@@ -320,7 +322,7 @@ endfunction
320
322
" TOPLEVEL .body
321
323
" COMMENT .str
322
324
" EXCMD .ea .str
323
- " FUNCTION .ea .body .left .rlist .attr .endfunction
325
+ " FUNCTION .ea .body .left .rlist .default_args . attr .endfunction
324
326
" ENDFUNCTION .ea
325
327
" DELFUNCTION .ea .left
326
328
" RETURN .ea .left
@@ -345,6 +347,7 @@ endfunction
345
347
" FINALLY .ea .body
346
348
" ENDTRY .ea
347
349
" THROW .ea .left
350
+ " EVAL .ea .left
348
351
" ECHO .ea .list
349
352
" ECHON .ea .list
350
353
" ECHOHL .ea .str
@@ -890,6 +893,8 @@ function! s:VimLParser._parse_command(parser) abort
890
893
call self .parse_cmd_tcl ()
891
894
elseif a: parser == # ' parse_cmd_throw'
892
895
call self .parse_cmd_throw ()
896
+ elseif a: parser == # ' parse_cmd_eval'
897
+ call self .parse_cmd_eval ()
893
898
elseif a: parser == # ' parse_cmd_try'
894
899
call self .parse_cmd_try ()
895
900
elseif a: parser == # ' parse_cmd_unlet'
@@ -1360,6 +1365,7 @@ function! s:VimLParser.parse_cmd_function() abort
1360
1365
let node.ea = self .ea
1361
1366
let node.left = left
1362
1367
let node.rlist = []
1368
+ let node.default_args = []
1363
1369
let node.attr = {' range' : 0 , ' abort' : 0 , ' dict' : 0 , ' closure' : 0 }
1364
1370
let node.endfunction = s: NIL
1365
1371
call self .reader.getn (1 )
@@ -1381,6 +1387,12 @@ function! s:VimLParser.parse_cmd_function() abort
1381
1387
let varnode.pos = token.pos
1382
1388
let varnode.value = token.value
1383
1389
call add (node.rlist, varnode)
1390
+ if tokenizer.peek ().type == # s: TOKEN_EQ
1391
+ call tokenizer.get ()
1392
+ call add (node.default_args, self .parse_expr ())
1393
+ elseif len (node.default_args) > 0
1394
+ throw s: Err (' E989: Non-default argument follows default argument' , varnode.pos)
1395
+ endif
1384
1396
" XXX: Vim doesn't skip white space before comma. F(a ,b) => E475
1385
1397
if s: iswhite (self .reader.p (0 )) && tokenizer.peek ().type == # s: TOKEN_COMMA
1386
1398
throw s: Err (' E475: Invalid argument: White space is not allowed before comma' , self .reader.getpos ())
@@ -1814,6 +1826,14 @@ function! s:VimLParser.parse_cmd_throw() abort
1814
1826
call self .add_node (node)
1815
1827
endfunction
1816
1828
1829
+ function ! s: VimLParser .parse_cmd_eval () abort
1830
+ let node = s: Node (s: NODE_EVAL )
1831
+ let node.pos = self .ea .cmdpos
1832
+ let node.ea = self .ea
1833
+ let node.left = self .parse_expr ()
1834
+ call self .add_node (node)
1835
+ endfunction
1836
+
1817
1837
function ! s: VimLParser .parse_cmd_echo () abort
1818
1838
let node = s: Node (s: NODE_ECHO )
1819
1839
let node.pos = self .ea .cmdpos
@@ -2217,6 +2237,7 @@ let s:VimLParser.builtin_commands = [
2217
2237
\ {' name' : ' endtry' , ' minlen' : 4 , ' flags' : ' TRLBAR|SBOXOK|CMDWIN' , ' parser' : ' parse_cmd_endtry' },
2218
2238
\ {' name' : ' endwhile' , ' minlen' : 4 , ' flags' : ' TRLBAR|SBOXOK|CMDWIN' , ' parser' : ' parse_cmd_endwhile' },
2219
2239
\ {' name' : ' enew' , ' minlen' : 3 , ' flags' : ' BANG|TRLBAR' , ' parser' : ' parse_cmd_common' },
2240
+ \ {' name' : ' eval' , ' minlen' : 2 , ' flags' : ' EXTRA|NOTRLCOM|SBOXOK|CMDWIN' , ' parser' : ' parse_cmd_eval' },
2220
2241
\ {' name' : ' ex' , ' minlen' : 2 , ' flags' : ' BANG|FILE1|EDITCMD|ARGOPT|TRLBAR' , ' parser' : ' parse_cmd_common' },
2221
2242
\ {' name' : ' execute' , ' minlen' : 3 , ' flags' : ' EXTRA|NOTRLCOM|SBOXOK|CMDWIN' , ' parser' : ' parse_cmd_execute' },
2222
2243
\ {' name' : ' exit' , ' minlen' : 3 , ' flags' : ' RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN' , ' parser' : ' parse_cmd_common' },
@@ -4778,6 +4799,9 @@ function! s:Compiler.compile(node) abort
4778
4799
elseif a: node .type == # s: NODE_EXCALL
4779
4800
call self .compile_excall (a: node )
4780
4801
return s: NIL
4802
+ elseif a: node .type == # s: NODE_EVAL
4803
+ call self .compile_eval (a: node )
4804
+ return s: NIL
4781
4805
elseif a: node .type == # s: NODE_LET
4782
4806
call self .compile_let (a: node )
4783
4807
return s: NIL
@@ -4980,14 +5004,25 @@ endfunction
4980
5004
function ! s: Compiler .compile_function (node) abort
4981
5005
let left = self .compile (a: node .left )
4982
5006
let rlist = map (a: node .rlist, ' self.compile(v:val)' )
4983
- if ! empty (rlist) && rlist[-1 ] == # ' ...'
4984
- let rlist[-1 ] = ' . ...'
4985
- endif
4986
- if empty (rlist)
4987
- call self .out (' (function (%s)' , left )
4988
- else
4989
- call self .out (' (function (%s %s)' , left , join (rlist, ' ' ))
5007
+ let default_args = map (a: node .default_args, ' self.compile(v:val)' )
5008
+ if ! empty (rlist)
5009
+ let remaining = s: FALSE
5010
+ if rlist[-1 ] == # ' ...'
5011
+ call remove (rlist, -1 )
5012
+ let remaining = s: TRUE
5013
+ endif
5014
+ for i in range (len (rlist))
5015
+ if i < len (rlist) - len (default_args)
5016
+ let left .= printf (' %s' , rlist[i ])
5017
+ else
5018
+ let left .= printf (' (%s %s)' , rlist[i ], default_args[i + len (default_args) - len (rlist)])
5019
+ endif
5020
+ endfor
5021
+ if remaining
5022
+ let left .= ' . ...'
5023
+ endif
4990
5024
endif
5025
+ call self .out (' (function (%s)' , left )
4991
5026
call self .incindent (' ' )
4992
5027
call self .compile_body (a: node .body)
4993
5028
call self .out (' )' )
@@ -5010,6 +5045,10 @@ function! s:Compiler.compile_excall(node) abort
5010
5045
call self .out (' (call %s)' , self .compile (a: node .left ))
5011
5046
endfunction
5012
5047
5048
+ function ! s: Compiler .compile_eval (node) abort
5049
+ call self .out (' (eval %s)' , self .compile (a: node .left ))
5050
+ endfunction
5051
+
5013
5052
function ! s: Compiler .compile_let (node) abort
5014
5053
let left = ' '
5015
5054
if a: node .left isnot # s: NIL
0 commit comments