Mercurial > vim
diff 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 |
line wrap: on
line diff
--- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1523,6 +1523,27 @@ generate_FUNCREF(cctx_T *cctx, int dfunc } /* + * Generate an ISN_NEWFUNC instruction. + */ + static int +generate_NEWFUNC(cctx_T *cctx, char_u *lambda_name, char_u *func_name) +{ + isn_T *isn; + char_u *name; + + RETURN_OK_IF_SKIP(cctx); + name = vim_strsave(lambda_name); + if (name == NULL) + return FAIL; + if ((isn = generate_instr(cctx, ISN_NEWFUNC)) == NULL) + return FAIL; + isn->isn_arg.newfunc.nf_lambda = name; + isn->isn_arg.newfunc.nf_global = func_name; + + return OK; +} + +/* * Generate an ISN_JUMP instruction. */ static int @@ -4875,11 +4896,13 @@ exarg_getline( static char_u * compile_nested_function(exarg_T *eap, cctx_T *cctx) { + int is_global = *eap->arg == 'g' && eap->arg[1] == ':'; char_u *name_start = eap->arg; - char_u *name_end = to_name_end(eap->arg, FALSE); + char_u *name_end = to_name_end(eap->arg, is_global); char_u *name = get_lambda_name(); lvar_T *lvar; ufunc_T *ufunc; + int r; eap->arg = name_end; eap->getline = exarg_getline; @@ -4894,16 +4917,28 @@ compile_nested_function(exarg_T *eap, cc && compile_def_function(ufunc, TRUE, cctx) == FAIL) return NULL; - // Define a local variable for the function reference. - lvar = reserve_local(cctx, name_start, name_end - name_start, + if (is_global) + { + char_u *func_name = vim_strnsave(name_start + 2, + name_end - name_start - 2); + + if (func_name == NULL) + r = FAIL; + else + r = generate_NEWFUNC(cctx, name, func_name); + } + else + { + // Define a local variable for the function reference. + lvar = reserve_local(cctx, name_start, name_end - name_start, TRUE, ufunc->uf_func_type); - - if (generate_FUNCREF(cctx, ufunc->uf_dfunc_idx) == FAIL - || generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL) == FAIL) - return NULL; + if (generate_FUNCREF(cctx, ufunc->uf_dfunc_idx) == FAIL) + return NULL; + r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); + } // TODO: warning for trailing text? - return (char_u *)""; + return r == FAIL ? NULL : (char_u *)""; } /* @@ -7641,6 +7676,11 @@ delete_instr(isn_T *isn) } break; + case ISN_NEWFUNC: + vim_free(isn->isn_arg.newfunc.nf_lambda); + vim_free(isn->isn_arg.newfunc.nf_global); + break; + case ISN_2BOOL: case ISN_2STRING: case ISN_ADDBLOB: