@@ -134,6 +134,7 @@ let s:NODE_ENV = 88
134
134
let s: NODE_REG = 89
135
135
let s: NODE_CURLYNAMEPART = 90
136
136
let s: NODE_CURLYNAMEEXPR = 91
137
+ let s: NODE_LAMBDA = 92
137
138
138
139
let s: TOKEN_EOF = 1
139
140
let s: TOKEN_EOL = 2
@@ -199,6 +200,7 @@ let s:TOKEN_SEMICOLON = 61
199
200
let s: TOKEN_BACKTICK = 62
200
201
let s: TOKEN_DOTDOTDOT = 63
201
202
let s: TOKEN_SHARP = 64
203
+ let s: TOKEN_ARROW = 65
202
204
203
205
let s: MAX_FUNC_ARGS = 20
204
206
@@ -398,6 +400,7 @@ endfunction
398
400
" REG .value
399
401
" CURLYNAMEPART .value
400
402
" CURLYNAMEEXPR .value
403
+ " LAMBDA .rlist .left
401
404
function ! s: Node (type )
402
405
return {' type' : a: type }
403
406
endfunction
@@ -2542,8 +2545,13 @@ function! s:ExprTokenizer.get2()
2542
2545
call r .seek_cur (1 )
2543
2546
return self .token (s: TOKEN_PLUS , ' +' , pos)
2544
2547
elseif c == # ' -'
2545
- call r .seek_cur (1 )
2546
- return self .token (s: TOKEN_MINUS , ' -' , pos)
2548
+ if r .p (1 ) == # ' >'
2549
+ call r .seek_cur (2 )
2550
+ return self .token (s: TOKEN_ARROW , ' ->' , pos)
2551
+ else
2552
+ call r .seek_cur (1 )
2553
+ return self .token (s: TOKEN_MINUS , ' -' , pos)
2554
+ endif
2547
2555
elseif c == # ' .'
2548
2556
if r .p (1 ) == # ' .' && r .p (2 ) == # ' .'
2549
2557
call r .seek_cur (3 )
@@ -3174,6 +3182,7 @@ endfunction
3174
3182
" 'string'
3175
3183
" [expr1, ...]
3176
3184
" {expr1: expr1, ...}
3185
+ " {args -> expr1}
3177
3186
" &option
3178
3187
" (expr1)
3179
3188
" variable
@@ -3225,13 +3234,20 @@ function! s:ExprParser.parse_expr9()
3225
3234
endwhile
3226
3235
endif
3227
3236
elseif token.type == s: TOKEN_COPEN
3228
- let node = s: Node (s: NODE_DICT )
3229
- let node.pos = token.pos
3230
- let node.value = []
3237
+ let node = s: Node (-1 )
3238
+ let p = token.pos
3231
3239
let token = self .tokenizer.peek ()
3232
3240
if token.type == s: TOKEN_CCLOSE
3241
+ " dict
3233
3242
call self .tokenizer.get ()
3234
- else
3243
+ let node = s: Node (s: NODE_DICT )
3244
+ let node.pos = p
3245
+ let node.value = []
3246
+ elseif token.type == s: TOKEN_DQUOTE || token.type == s: TOKEN_SQUOTE
3247
+ " dict
3248
+ let node = s: Node (s: NODE_DICT )
3249
+ let node.pos = p
3250
+ let node.value = []
3235
3251
while 1
3236
3252
let key = self .parse_expr1 ()
3237
3253
let token = self .tokenizer.get ()
@@ -3260,6 +3276,72 @@ function! s:ExprParser.parse_expr9()
3260
3276
throw s: Err (printf (' unexpected token: %s' , token.value), token.pos)
3261
3277
endif
3262
3278
endwhile
3279
+ else
3280
+ " lambda ref: s:NODE_FUNCTION
3281
+ let node = s: Node (s: NODE_LAMBDA )
3282
+ let node.pos = p
3283
+ let node.rlist = []
3284
+ let named = {}
3285
+ while 1
3286
+ let token = self .tokenizer.get ()
3287
+ if token.type == s: TOKEN_ARROW
3288
+ break
3289
+ elseif token.type == s: TOKEN_IDENTIFIER
3290
+ if ! s: isargname (token.value)
3291
+ throw s: Err (printf (' E125: Illegal argument: %s' , token.value), token.pos)
3292
+ elseif has_key (named, token.value)
3293
+ throw s: Err (printf (' E853: Duplicate argument name: %s' , token.value), token.pos)
3294
+ endif
3295
+ let named[token.value] = 1
3296
+ let varnode = s: Node (s: NODE_IDENTIFIER )
3297
+ let varnode.pos = token.pos
3298
+ let varnode.value = token.value
3299
+ " XXX: Vim doesn't skip white space before comma. {a ,b -> ...} => E475
3300
+ if s: iswhite (self .reader.p (0 )) && self .tokenizer.peek ().type == s: TOKEN_COMMA
3301
+ throw s: Err (' E475: Invalid argument: White space is not allowed before comma' , self .reader.getpos ())
3302
+ endif
3303
+ let token = self .tokenizer.get ()
3304
+ " handle curly_parts
3305
+ if token.type == s: TOKEN_COPEN || token.type == s: TOKEN_CCLOSE
3306
+ if ! empty (node.rlist)
3307
+ throw s: Err (printf (' unexpected token: %s' , token.value), token.pos)
3308
+ endif
3309
+ call self .reader.seek_set (pos)
3310
+ let node = self .parse_identifier ()
3311
+ return node
3312
+ endif
3313
+ call add (node.rlist, varnode)
3314
+ if token.type == s: TOKEN_COMMA
3315
+ " XXX: Vim allows last comma. {a, b, -> ...} => OK
3316
+ if self .reader.peekn (2 ) == s: TOKEN_ARROW
3317
+ call self .tokenizer.get ()
3318
+ break
3319
+ endif
3320
+ elseif token.type == s: TOKEN_ARROW
3321
+ break
3322
+ else
3323
+ throw s: Err (printf (' unexpected token: %s, type: %d' , token.value, token.type ), token.pos)
3324
+ endif
3325
+ elseif token.type == s: TOKEN_DOTDOTDOT
3326
+ let varnode = s: Node (s: NODE_IDENTIFIER )
3327
+ let varnode.pos = token.pos
3328
+ let varnode.value = token.value
3329
+ call add (node.rlist, varnode)
3330
+ let token = self .tokenizer.get ()
3331
+ if token.type == s: TOKEN_ARROW
3332
+ break
3333
+ else
3334
+ throw s: Err (printf (' unexpected token: %s' , token.value), token.pos)
3335
+ endif
3336
+ else
3337
+ throw s: Err (printf (' unexpected token: %s' , token.value), token.pos)
3338
+ endif
3339
+ endwhile
3340
+ let node.left = self .parse_expr1 ()
3341
+ let token = self .tokenizer.get ()
3342
+ if token.type != s: TOKEN_CCLOSE
3343
+ throw s: Err (printf (' unexpected token: %s' , token.value), token.pos)
3344
+ endif
3263
3345
endif
3264
3346
elseif token.type == s: TOKEN_POPEN
3265
3347
let node = self .parse_expr1 ()
@@ -3929,6 +4011,8 @@ function! s:Compiler.compile(node)
3929
4011
return self .compile_curlynamepart (a: node )
3930
4012
elseif a: node .type == s: NODE_CURLYNAMEEXPR
3931
4013
return self .compile_curlynameexpr (a: node )
4014
+ elseif a: node .type == s: NODE_LAMBDA
4015
+ return self .compile_lambda (a: node )
3932
4016
else
3933
4017
throw printf (' Compiler: unknown node: %s' , string (a: node ))
3934
4018
endif
@@ -4384,6 +4468,11 @@ function! s:Compiler.compile_curlynameexpr(node)
4384
4468
return ' {' . self .compile (a: node .value) . ' }'
4385
4469
endfunction
4386
4470
4471
+ function ! s: Compiler .compile_lambda (node)
4472
+ let rlist = map (a: node .rlist, ' self.compile(v:val)' )
4473
+ return printf (' (lambda (%s) %s)' , join (rlist, ' ' ), self .compile (a: node .left ))
4474
+ endfunction
4475
+
4387
4476
" TODO: under construction
4388
4477
let s: RegexpParser = {}
4389
4478
0 commit comments