diff src/vim9compile.c @ 24590:2818f846f099 v8.2.2834

patch 8.2.2834: Vim9: :cexpr does not work with local variables Commit: https://github.com/vim/vim/commit/5f7d4c049e934dbc8d2c3f2720797c10ee3c55c2 Author: Bram Moolenaar <Bram@vim.org> Date: Wed May 5 21:31:39 2021 +0200 patch 8.2.2834: Vim9: :cexpr does not work with local variables Problem: Vim9: :cexpr does not work with local variables. Solution: Compile :cexpr.
author Bram Moolenaar <Bram@vim.org>
date Wed, 05 May 2021 21:45:04 +0200
parents 3a290891a015
children ae2eb2c496ed
line wrap: on
line diff
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -8704,6 +8704,34 @@ compile_redir(char_u *line, exarg_T *eap
     return compile_exec(line, eap, cctx);
 }
 
+    static char_u *
+compile_cexpr(char_u *line, exarg_T *eap, cctx_T *cctx)
+{
+    isn_T	*isn;
+    char_u	*p;
+
+    isn = generate_instr(cctx, ISN_CEXPR_AUCMD);
+    if (isn == NULL)
+	return NULL;
+    isn->isn_arg.number = eap->cmdidx;
+
+    p = eap->arg;
+    if (compile_expr0(&p, cctx) == FAIL)
+	return NULL;
+
+    isn = generate_instr(cctx, ISN_CEXPR_CORE);
+    if (isn == NULL)
+	return NULL;
+    isn->isn_arg.cexpr.cexpr_ref = ALLOC_ONE(cexprref_T);
+    if (isn->isn_arg.cexpr.cexpr_ref == NULL)
+	return NULL;
+    isn->isn_arg.cexpr.cexpr_ref->cer_cmdidx = eap->cmdidx;
+    isn->isn_arg.cexpr.cexpr_ref->cer_forceit = eap->forceit;
+    isn->isn_arg.cexpr.cexpr_ref->cer_cmdline = vim_strsave(skipwhite(line));
+
+    return p;
+}
+
 /*
  * Add a function to the list of :def functions.
  * This sets "ufunc->uf_dfunc_idx" but the function isn't compiled yet.
@@ -9262,6 +9290,16 @@ compile_def_function(
 		    line = compile_redir(line, &ea, &cctx);
 		    break;
 
+	    case CMD_cexpr:
+	    case CMD_lexpr:
+	    case CMD_caddexpr:
+	    case CMD_laddexpr:
+	    case CMD_cgetexpr:
+	    case CMD_lgetexpr:
+		    ea.arg = p;
+		    line = compile_cexpr(line, &ea, &cctx);
+		    break;
+
 	    // TODO: any other commands with an expression argument?
 
 	    case CMD_append:
@@ -9602,6 +9640,10 @@ delete_instr(isn_T *isn)
 	    vim_free(isn->isn_arg.try.try_ref);
 	    break;
 
+	case ISN_CEXPR_CORE:
+	    vim_free(isn->isn_arg.cexpr.cexpr_ref);
+	    break;
+
 	case ISN_2BOOL:
 	case ISN_2STRING:
 	case ISN_2STRING_ANY:
@@ -9614,6 +9656,7 @@ delete_instr(isn_T *isn)
 	case ISN_BLOBINDEX:
 	case ISN_BLOBSLICE:
 	case ISN_CATCH:
+	case ISN_CEXPR_AUCMD:
 	case ISN_CHECKLEN:
 	case ISN_CHECKNR:
 	case ISN_CMDMOD_REV: