diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-09-03 21:35:53 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-09-03 21:35:53 +0100 |
commit | 1d84f7608f1e41dad03b8cc7925895437775f7c0 (patch) | |
tree | cc276825566021a35b96f93e178e5f2ac621a84b /src/vim9cmds.c | |
parent | 06d32a0c177e4166ff0491668cd459464bc2ef45 (diff) | |
download | vim-git-1d84f7608f1e41dad03b8cc7925895437775f7c0.tar.gz |
patch 9.0.0370: cleaning up afterwards can make a function messyv9.0.0370
Problem: Cleaning up afterwards can make a function messy.
Solution: Add the :defer command.
Diffstat (limited to 'src/vim9cmds.c')
-rw-r--r-- | src/vim9cmds.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/vim9cmds.c b/src/vim9cmds.c index 4ad87bc26..9651801ed 100644 --- a/src/vim9cmds.c +++ b/src/vim9cmds.c @@ -1654,6 +1654,9 @@ compile_throw(char_u *arg, cctx_T *cctx UNUSED) return p; } +/* + * Compile an expression or function call. + */ char_u * compile_eval(char_u *arg, cctx_T *cctx) { @@ -1682,6 +1685,67 @@ compile_eval(char_u *arg, cctx_T *cctx) } /* + * Compile "defer func(arg)". + */ + char_u * +compile_defer(char_u *arg_start, cctx_T *cctx) +{ + char_u *p; + char_u *arg = arg_start; + int argcount = 0; + dfunc_T *dfunc; + type_T *type; + int func_idx; + + // Get a funcref for the function name. + // TODO: better way to find the "(". + p = vim_strchr(arg, '('); + if (p == NULL) + { + semsg(_(e_missing_parenthesis_str), arg); + return NULL; + } + *p = NUL; + func_idx = find_internal_func(arg); + if (func_idx >= 0) + // TODO: better type + generate_PUSHFUNC(cctx, (char_u *)internal_func_name(func_idx), + &t_func_any, FALSE); + else if (compile_expr0(&arg, cctx) == FAIL) + return NULL; + *p = '('; + + // check for function type + type = get_type_on_stack(cctx, 0); + if (type->tt_type != VAR_FUNC) + { + emsg(_(e_function_name_required)); + return NULL; + } + + // compile the arguments + arg = skipwhite(p + 1); + if (compile_arguments(&arg, cctx, &argcount, CA_NOT_SPECIAL) == FAIL) + return NULL; + + // TODO: check argument count with "type" + + dfunc = ((dfunc_T *)def_functions.ga_data) + cctx->ctx_ufunc->uf_dfunc_idx; + if (dfunc->df_defer_var_idx == 0) + { + lvar_T *lvar = reserve_local(cctx, (char_u *)"@defer@", 7, + TRUE, &t_list_any); + if (lvar == NULL) + return NULL; + dfunc->df_defer_var_idx = lvar->lv_idx + 1; + } + if (generate_DEFER(cctx, dfunc->df_defer_var_idx - 1, argcount) == FAIL) + return NULL; + + return skipwhite(arg); +} + +/* * compile "echo expr" * compile "echomsg expr" * compile "echoerr expr" |