comparison src/userfunc.c @ 20279:49b50843e725 v8.2.0695

patch 8.2.0695: Vim9: cannot define a function inside a function Commit: https://github.com/vim/vim/commit/04b12697838b232b8b17c553ccc74cf1f1bdb81c Author: Bram Moolenaar <Bram@vim.org> Date: Mon May 4 23:24:44 2020 +0200 patch 8.2.0695: Vim9: cannot define a function inside a function Problem: Vim9: cannot define a function inside a function. Solution: Initial support for :def inside :def.
author Bram Moolenaar <Bram@vim.org>
date Mon, 04 May 2020 23:30:04 +0200
parents 683c2da4982b
children 7587d892c00c
comparison
equal deleted inserted replaced
20278:4148ba869078 20279:49b50843e725
327 } 327 }
328 } 328 }
329 } 329 }
330 330
331 /* 331 /*
332 * Get a name for a lambda. Returned in static memory.
333 */
334 char_u *
335 get_lambda_name(void)
336 {
337 static char_u name[30];
338 static int lambda_no = 0;
339
340 sprintf((char*)name, "<lambda>%d", ++lambda_no);
341 return name;
342 }
343
344 /*
332 * Parse a lambda expression and get a Funcref from "*arg". 345 * Parse a lambda expression and get a Funcref from "*arg".
333 * Return OK or FAIL. Returns NOTDONE for dict or {expr}. 346 * Return OK or FAIL. Returns NOTDONE for dict or {expr}.
334 */ 347 */
335 int 348 int
336 get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate) 349 get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate)
342 partial_T *pt = NULL; 355 partial_T *pt = NULL;
343 int varargs; 356 int varargs;
344 int ret; 357 int ret;
345 char_u *start = skipwhite(*arg + 1); 358 char_u *start = skipwhite(*arg + 1);
346 char_u *s, *e; 359 char_u *s, *e;
347 static int lambda_no = 0;
348 int *old_eval_lavars = eval_lavars_used; 360 int *old_eval_lavars = eval_lavars_used;
349 int eval_lavars = FALSE; 361 int eval_lavars = FALSE;
350 362
351 ga_init(&newargs); 363 ga_init(&newargs);
352 ga_init(&newlines); 364 ga_init(&newlines);
390 402
391 if (evaluate) 403 if (evaluate)
392 { 404 {
393 int len, flags = 0; 405 int len, flags = 0;
394 char_u *p; 406 char_u *p;
395 char_u name[20]; 407 char_u *name = get_lambda_name();
396
397 sprintf((char*)name, "<lambda>%d", ++lambda_no);
398 408
399 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); 409 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
400 if (fp == NULL) 410 if (fp == NULL)
401 goto errret; 411 goto errret;
402 fp->uf_dfunc_idx = -1; 412 fp->uf_dfunc_idx = -1;
2362 } 2372 }
2363 return NULL; 2373 return NULL;
2364 } 2374 }
2365 2375
2366 /* 2376 /*
2367 * ":function" 2377 * ":function" also supporting nested ":def".
2368 */ 2378 * Returns a pointer to the function or NULL if no function defined.
2369 void 2379 */
2370 ex_function(exarg_T *eap) 2380 ufunc_T *
2381 def_function(exarg_T *eap, char_u *name_arg, void *context)
2371 { 2382 {
2372 char_u *theline; 2383 char_u *theline;
2373 char_u *line_to_free = NULL; 2384 char_u *line_to_free = NULL;
2374 int j; 2385 int j;
2375 int c; 2386 int c;
2376 int saved_did_emsg; 2387 int saved_did_emsg;
2377 int saved_wait_return = need_wait_return; 2388 int saved_wait_return = need_wait_return;
2378 char_u *name = NULL; 2389 char_u *name = name_arg;
2379 int is_global = FALSE; 2390 int is_global = FALSE;
2380 char_u *p; 2391 char_u *p;
2381 char_u *arg; 2392 char_u *arg;
2382 char_u *line_arg = NULL; 2393 char_u *line_arg = NULL;
2383 garray_T newargs; 2394 garray_T newargs;
2385 garray_T default_args; 2396 garray_T default_args;
2386 garray_T newlines; 2397 garray_T newlines;
2387 int varargs = FALSE; 2398 int varargs = FALSE;
2388 int flags = 0; 2399 int flags = 0;
2389 char_u *ret_type = NULL; 2400 char_u *ret_type = NULL;
2390 ufunc_T *fp; 2401 ufunc_T *fp = NULL;
2391 int overwrite = FALSE; 2402 int overwrite = FALSE;
2392 int indent; 2403 int indent;
2393 int nesting; 2404 int nesting;
2394 #define MAX_FUNC_NESTING 50 2405 #define MAX_FUNC_NESTING 50
2395 char nesting_def[MAX_FUNC_NESTING]; 2406 char nesting_def[MAX_FUNC_NESTING];
2427 list_func_head(fp, FALSE); 2438 list_func_head(fp, FALSE);
2428 } 2439 }
2429 } 2440 }
2430 } 2441 }
2431 eap->nextcmd = check_nextcmd(eap->arg); 2442 eap->nextcmd = check_nextcmd(eap->arg);
2432 return; 2443 return NULL;
2433 } 2444 }
2434 2445
2435 /* 2446 /*
2436 * ":function /pat": list functions matching pattern. 2447 * ":function /pat": list functions matching pattern.
2437 */ 2448 */
2467 } 2478 }
2468 } 2479 }
2469 if (*p == '/') 2480 if (*p == '/')
2470 ++p; 2481 ++p;
2471 eap->nextcmd = check_nextcmd(p); 2482 eap->nextcmd = check_nextcmd(p);
2472 return; 2483 return NULL;
2473 } 2484 }
2474 2485
2475 ga_init(&newargs); 2486 ga_init(&newargs);
2476 ga_init(&argtypes); 2487 ga_init(&argtypes);
2477 ga_init(&default_args); 2488 ga_init(&default_args);
2491 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 2502 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL
2492 * s:func script-local function name 2503 * s:func script-local function name
2493 * g:func global function name, same as "func" 2504 * g:func global function name, same as "func"
2494 */ 2505 */
2495 p = eap->arg; 2506 p = eap->arg;
2496 name = trans_function_name(&p, &is_global, eap->skip, 2507 if (name_arg != NULL)
2508 {
2509 // nested function, argument is (args).
2510 paren = TRUE;
2511 CLEAR_FIELD(fudi);
2512 }
2513 else
2514 {
2515 name = trans_function_name(&p, &is_global, eap->skip,
2497 TFN_NO_AUTOLOAD, &fudi, NULL); 2516 TFN_NO_AUTOLOAD, &fudi, NULL);
2498 paren = (vim_strchr(p, '(') != NULL); 2517 paren = (vim_strchr(p, '(') != NULL);
2499 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 2518 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip)
2500 { 2519 {
2501 /* 2520 /*
2502 * Return on an invalid expression in braces, unless the expression 2521 * Return on an invalid expression in braces, unless the expression
2503 * evaluation has been cancelled due to an aborting error, an 2522 * evaluation has been cancelled due to an aborting error, an
2504 * interrupt, or an exception. 2523 * interrupt, or an exception.
2505 */ 2524 */
2506 if (!aborting()) 2525 if (!aborting())
2507 { 2526 {
2508 if (!eap->skip && fudi.fd_newkey != NULL) 2527 if (!eap->skip && fudi.fd_newkey != NULL)
2509 semsg(_(e_dictkey), fudi.fd_newkey); 2528 semsg(_(e_dictkey), fudi.fd_newkey);
2510 vim_free(fudi.fd_newkey); 2529 vim_free(fudi.fd_newkey);
2511 return; 2530 return NULL;
2512 } 2531 }
2513 else 2532 else
2514 eap->skip = TRUE; 2533 eap->skip = TRUE;
2534 }
2515 } 2535 }
2516 2536
2517 // An error in a function call during evaluation of an expression in magic 2537 // An error in a function call during evaluation of an expression in magic
2518 // braces should not cause the function not to be defined. 2538 // braces should not cause the function not to be defined.
2519 saved_did_emsg = did_emsg; 2539 saved_did_emsg = did_emsg;
2594 } 2614 }
2595 p = skipwhite(p + 1); 2615 p = skipwhite(p + 1);
2596 2616
2597 ga_init2(&newlines, (int)sizeof(char_u *), 3); 2617 ga_init2(&newlines, (int)sizeof(char_u *), 3);
2598 2618
2599 if (!eap->skip) 2619 if (!eap->skip && name_arg == NULL)
2600 { 2620 {
2601 // Check the name of the function. Unless it's a dictionary function 2621 // Check the name of the function. Unless it's a dictionary function
2602 // (that we are overwriting). 2622 // (that we are overwriting).
2603 if (name != NULL) 2623 if (name != NULL)
2604 arg = name; 2624 arg = name;
3253 is_export = FALSE; 3273 is_export = FALSE;
3254 } 3274 }
3255 3275
3256 // ":def Func()" needs to be compiled 3276 // ":def Func()" needs to be compiled
3257 if (eap->cmdidx == CMD_def) 3277 if (eap->cmdidx == CMD_def)
3258 compile_def_function(fp, FALSE, NULL); 3278 compile_def_function(fp, FALSE, context);
3259 3279
3260 goto ret_free; 3280 goto ret_free;
3261 3281
3262 erret: 3282 erret:
3263 ga_clear_strings(&newargs); 3283 ga_clear_strings(&newargs);
3267 ret_free: 3287 ret_free:
3268 ga_clear_strings(&argtypes); 3288 ga_clear_strings(&argtypes);
3269 vim_free(skip_until); 3289 vim_free(skip_until);
3270 vim_free(line_to_free); 3290 vim_free(line_to_free);
3271 vim_free(fudi.fd_newkey); 3291 vim_free(fudi.fd_newkey);
3272 vim_free(name); 3292 if (name != name_arg)
3293 vim_free(name);
3273 vim_free(ret_type); 3294 vim_free(ret_type);
3274 did_emsg |= saved_did_emsg; 3295 did_emsg |= saved_did_emsg;
3275 need_wait_return |= saved_wait_return; 3296 need_wait_return |= saved_wait_return;
3297
3298 return fp;
3299 }
3300
3301 /*
3302 * ":function"
3303 */
3304 void
3305 ex_function(exarg_T *eap)
3306 {
3307 def_function(eap, NULL, NULL);
3276 } 3308 }
3277 3309
3278 /* 3310 /*
3279 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 3311 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).
3280 * Return 2 if "p" starts with "s:". 3312 * Return 2 if "p" starts with "s:".