Mercurial > vim
comparison src/vim9compile.c @ 21558:1c4d4aa22b37 v8.2.1329
patch 8.2.1329: Vim9: cannot define global function inside :def function
Commit: https://github.com/vim/vim/commit/38ddf333f6b2806b0ea2dd052ee1cd50dd7f4525
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Jul 31 22:05:04 2020 +0200
patch 8.2.1329: Vim9: cannot define global function inside :def function
Problem: Vim9: cannot define global function inside :def function.
Solution: Assign to global variable instead of local. (closes https://github.com/vim/vim/issues/6584)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 31 Jul 2020 22:15:04 +0200 |
parents | 4d3e983313dc |
children | 55aa283a0e5e |
comparison
equal
deleted
inserted
replaced
21557:00c9f8522652 | 21558:1c4d4aa22b37 |
---|---|
1516 if (ga_grow(stack, 1) == FAIL) | 1516 if (ga_grow(stack, 1) == FAIL) |
1517 return FAIL; | 1517 return FAIL; |
1518 ((type_T **)stack->ga_data)[stack->ga_len] = &t_func_any; | 1518 ((type_T **)stack->ga_data)[stack->ga_len] = &t_func_any; |
1519 // TODO: argument and return types | 1519 // TODO: argument and return types |
1520 ++stack->ga_len; | 1520 ++stack->ga_len; |
1521 | |
1522 return OK; | |
1523 } | |
1524 | |
1525 /* | |
1526 * Generate an ISN_NEWFUNC instruction. | |
1527 */ | |
1528 static int | |
1529 generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name) | |
1530 { | |
1531 isn_T *isn; | |
1532 char_u *name; | |
1533 | |
1534 RETURN_OK_IF_SKIP(cctx); | |
1535 name = vim_strsave(lambda_name); | |
1536 if (name == NULL) | |
1537 return FAIL; | |
1538 if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL) | |
1539 return FAIL; | |
1540 isn->isn_arg.newfunc.nf_lambda = name; | |
1541 isn->isn_arg.newfunc.nf_global = func_name; | |
1521 | 1542 |
1522 return OK; | 1543 return OK; |
1523 } | 1544 } |
1524 | 1545 |
1525 /* | 1546 /* |
4873 * Compile a nested :def command. | 4894 * Compile a nested :def command. |
4874 */ | 4895 */ |
4875 static char_u * | 4896 static char_u * |
4876 compile_nested_function(exarg_T *eap, cctx_T *cctx) | 4897 compile_nested_function(exarg_T *eap, cctx_T *cctx) |
4877 { | 4898 { |
4899 int is_global = *eap->arg == 'g' && eap->arg[1] == ':'; | |
4878 char_u *name_start = eap->arg; | 4900 char_u *name_start = eap->arg; |
4879 char_u *name_end = to_name_end(eap->arg, FALSE); | 4901 char_u *name_end = to_name_end(eap->arg, is_global); |
4880 char_u *name = get_lambda_name(); | 4902 char_u *name = get_lambda_name(); |
4881 lvar_T *lvar; | 4903 lvar_T *lvar; |
4882 ufunc_T *ufunc; | 4904 ufunc_T *ufunc; |
4905 int r; | |
4883 | 4906 |
4884 eap->arg = name_end; | 4907 eap->arg = name_end; |
4885 eap->getline = exarg_getline; | 4908 eap->getline = exarg_getline; |
4886 eap->cookie = cctx; | 4909 eap->cookie = cctx; |
4887 eap->skip = cctx->ctx_skip == SKIP_YES; | 4910 eap->skip = cctx->ctx_skip == SKIP_YES; |
4892 return NULL; | 4915 return NULL; |
4893 if (ufunc->uf_def_status == UF_TO_BE_COMPILED | 4916 if (ufunc->uf_def_status == UF_TO_BE_COMPILED |
4894 && compile_def_function(ufunc, TRUE, cctx) == FAIL) | 4917 && compile_def_function(ufunc, TRUE, cctx) == FAIL) |
4895 return NULL; | 4918 return NULL; |
4896 | 4919 |
4897 // Define a local variable for the function reference. | 4920 if (is_global) |
4898 lvar = reserve_local(cctx, name_start, name_end - name_start, | 4921 { |
4922 char_u *func_name = vim_strnsave(name_start + 2, | |
4923 name_end - name_start - 2); | |
4924 | |
4925 if (func_name == NULL) | |
4926 r = FAIL; | |
4927 else | |
4928 r = generate_NEWFUNC(cctx, name, func_name); | |
4929 } | |
4930 else | |
4931 { | |
4932 // Define a local variable for the function reference. | |
4933 lvar = reserve_local(cctx, name_start, name_end - name_start, | |
4899 TRUE, ufunc->uf_func_type); | 4934 TRUE, ufunc->uf_func_type); |
4900 | 4935 if (generate_FUNCREF(cctx, ufunc->uf_dfunc_idx) == FAIL) |
4901 if (generate_FUNCREF(cctx, ufunc->uf_dfunc_idx) == FAIL | 4936 return NULL; |
4902 || generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL) == FAIL) | 4937 r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); |
4903 return NULL; | 4938 } |
4904 | 4939 |
4905 // TODO: warning for trailing text? | 4940 // TODO: warning for trailing text? |
4906 return (char_u *)""; | 4941 return r == FAIL ? NULL : (char_u *)""; |
4907 } | 4942 } |
4908 | 4943 |
4909 /* | 4944 /* |
4910 * Return the length of an assignment operator, or zero if there isn't one. | 4945 * Return the length of an assignment operator, or zero if there isn't one. |
4911 */ | 4946 */ |
7637 { | 7672 { |
7638 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) | 7673 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) |
7639 + isn->isn_arg.funcref.fr_func; | 7674 + isn->isn_arg.funcref.fr_func; |
7640 func_ptr_unref(dfunc->df_ufunc); | 7675 func_ptr_unref(dfunc->df_ufunc); |
7641 } | 7676 } |
7677 break; | |
7678 | |
7679 case ISN_NEWFUNC: | |
7680 vim_free(isn->isn_arg.newfunc.nf_lambda); | |
7681 vim_free(isn->isn_arg.newfunc.nf_global); | |
7642 break; | 7682 break; |
7643 | 7683 |
7644 case ISN_2BOOL: | 7684 case ISN_2BOOL: |
7645 case ISN_2STRING: | 7685 case ISN_2STRING: |
7646 case ISN_ADDBLOB: | 7686 case ISN_ADDBLOB: |