diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-04-19 16:28:59 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-04-19 16:28:59 +0200 |
commit | d72c1bf0a6784afdc8d8ceab4a007cd76d5b81e1 (patch) | |
tree | a7e9a7f882a81830fa5225db9f4057d3eb13615c /src/vim9compile.c | |
parent | d3aac2917db38f8590648ee76eebfa178fc4c069 (diff) |
patch 8.2.0601: Vim9: :unlet is not compiledv8.2.0601
Problem: Vim9: :unlet is not compiled.
Solution: Implement :unlet instruction and check for errors.
Diffstat (limited to 'src/vim9compile.c')
-rw-r--r-- | src/vim9compile.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/vim9compile.c b/src/vim9compile.c index c99d39602e..c4a5c08d89 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -987,6 +987,23 @@ generate_LOADV( } /* + * Generate an ISN_UNLET instruction. + */ + static int +generate_UNLET(cctx_T *cctx, char_u *name, int forceit) +{ + isn_T *isn; + + RETURN_OK_IF_SKIP(cctx); + if ((isn = generate_instr(cctx, ISN_UNLET)) == NULL) + return FAIL; + isn->isn_arg.unlet.ul_name = vim_strsave(name); + isn->isn_arg.unlet.ul_forceit = forceit; + + return OK; +} + +/* * Generate an ISN_LOADS instruction. */ static int @@ -4543,6 +4560,81 @@ theend: } /* + * Check if "name" can be "unlet". + */ + int +check_vim9_unlet(char_u *name) +{ + if (name[1] != ':' || vim_strchr((char_u *)"gwtb", *name) == NULL) + { + semsg(_("E1081: Cannot unlet %s"), name); + return FAIL; + } + return OK; +} + +/* + * Callback passed to ex_unletlock(). + */ + static int +compile_unlet( + lval_T *lvp, + char_u *name_end, + exarg_T *eap, + int deep UNUSED, + void *coookie) +{ + cctx_T *cctx = coookie; + + if (lvp->ll_tv == NULL) + { + char_u *p = lvp->ll_name; + int cc = *name_end; + int ret = OK; + + // Normal name. Only supports g:, w:, t: and b: namespaces. + *name_end = NUL; + if (check_vim9_unlet(p) == FAIL) + ret = FAIL; + else + ret = generate_UNLET(cctx, p, eap->forceit); + + *name_end = cc; + return ret; + } + + // TODO: unlet {list}[idx] + // TODO: unlet {dict}[key] + emsg("Sorry, :unlet not fully implemented yet"); + return FAIL; +} + +/* + * compile "unlet var", "lock var" and "unlock var" + * "arg" points to "var". + */ + static char_u * +compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx) +{ + char_u *p = arg; + + if (eap->cmdidx != CMD_unlet) + { + emsg("Sorry, :lock and unlock not implemented yet"); + return NULL; + } + + if (*p == '!') + { + p = skipwhite(p + 1); + eap->forceit = TRUE; + } + + ex_unletlock(eap, p, 0, GLV_NO_AUTOLOAD, compile_unlet, cctx); + return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd; +} + +/* * Compile an :import command. */ static char_u * @@ -6031,6 +6123,12 @@ compile_def_function(ufunc_T *ufunc, int set_return_type) line = compile_assignment(p, &ea, ea.cmdidx, &cctx); break; + case CMD_unlet: + case CMD_unlockvar: + case CMD_lockvar: + line = compile_unletlock(p, &ea, &cctx); + break; + case CMD_import: line = compile_import(p, &cctx); break; @@ -6264,6 +6362,10 @@ delete_instr(isn_T *isn) vim_free(isn->isn_arg.loadstore.ls_name); break; + case ISN_UNLET: + vim_free(isn->isn_arg.unlet.ul_name); + break; + case ISN_STOREOPT: vim_free(isn->isn_arg.storeopt.so_name); break; |