aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-04-14 07:11:59 +0800
committerGitHub <noreply@github.com>2023-04-14 07:11:59 +0800
commit8f69c5ed450337b9f77c50f9ee0d3eb32f649ca6 (patch)
tree20ce18a0515f58ae6aa955cf40ac3d73bc96603f /src/nvim/eval
parent0adb9f75c52424c8839708f51294ca5f58a3c18f (diff)
downloadrneovim-8f69c5ed450337b9f77c50f9ee0d3eb32f649ca6.tar.gz
rneovim-8f69c5ed450337b9f77c50f9ee0d3eb32f649ca6.tar.bz2
rneovim-8f69c5ed450337b9f77c50f9ee0d3eb32f649ca6.zip
vim-patch:8.2.{0695,0725,0734,0753,0818,0819,0822} (#23075)
vim-patch:8.2.0695: Vim9: cannot define a function inside a function Problem: Vim9: cannot define a function inside a function. Solution: Initial support for :def inside :def. https://github.com/vim/vim/commit/04b12697838b232b8b17c553ccc74cf1f1bdb81c vim-patch:8.2.0725: Vim9: cannot call a function declared later in Vim9 script Problem: Vim9: cannot call a function declared later in Vim9 script. Solution: Make two passes through the script file. https://github.com/vim/vim/commit/09689a02840be40fa7bb10b1921fb5bc5b2908f1 vim-patch:8.2.0734: Vim9: leaking memory when using :finish Problem: Vim9: leaking memory when using :finish. Solution: Do not check for next line in third pass. https://github.com/vim/vim/commit/04816717dfea6e2469ff4c9d40f68b59aaf03724 vim-patch:8.2.0753: Vim9: expressions are evaluated in the discovery phase Problem: Vim9: expressions are evaluated in the discovery phase. Solution: Bail out if an expression is not a constant. Require a type for declared constants. https://github.com/vim/vim/commit/32e351179eacfc84f64cd5029e221582d400bb38 vim-patch:8.2.0818: Vim9: using a discovery phase doesn't work well Problem: Vim9: using a discovery phase doesn't work well. Solution: Remove the discovery phase, instead compile a function only when it is used. Add :defcompile to compile def functions earlier. https://github.com/vim/vim/commit/822ba24743af9ee1b5e7f656a7a61a38f3638bca vim-patch:8.2.0819: compiler warning for unused variable Problem: Compiler warning for unused variable. Solution: Remove the variable. https://github.com/vim/vim/commit/f40e51a880a95f94dbbbecc9476559506c2cc345 vim-patch:8.2.0822: Vim9: code left over from discovery phase Problem: Vim9: code left over from discovery phase. Solution: Remove the dead code. https://github.com/vim/vim/commit/2eec37926db6d31beb36f162ac00357a30c093c8 Co-authored-by: Bram Moolenaar <Bram@vim.org>
Diffstat (limited to 'src/nvim/eval')
-rw-r--r--src/nvim/eval/funcs.c2
-rw-r--r--src/nvim/eval/userfunc.c15
-rw-r--r--src/nvim/eval/vars.c29
3 files changed, 22 insertions, 24 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 7f224f371c..52e38b73ba 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -1550,7 +1550,7 @@ static void f_eval(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
}
const char *const expr_start = s;
- if (s == NULL || eval1((char **)&s, rettv, true) == FAIL) {
+ if (s == NULL || eval1((char **)&s, rettv, EVAL_EVALUATE) == FAIL) {
if (expr_start != NULL && !aborting()) {
semsg(_(e_invexpr2), expr_start);
}
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index f09da6b79b..f82ab08d2d 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -152,7 +152,7 @@ static int get_function_args(char **argp, char endchar, garray_T *newargs, int *
p = skipwhite(p) + 1;
p = skipwhite(p);
char *expr = p;
- if (eval1(&p, &rettv, false) != FAIL) {
+ if (eval1(&p, &rettv, 0) != FAIL) {
ga_grow(default_args, 1);
// trim trailing whitespace
@@ -463,7 +463,8 @@ int get_func_tv(const char *name, int len, typval_T *rettv, char **arg, funcexe_
if (*argp == ')' || *argp == ',' || *argp == NUL) {
break;
}
- if (eval1(&argp, &argvars[argcount], funcexe->fe_evaluate) == FAIL) {
+ if (eval1(&argp, &argvars[argcount],
+ funcexe->fe_evaluate ? EVAL_EVALUATE : 0) == FAIL) {
ret = FAIL;
break;
}
@@ -972,7 +973,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
default_expr = ((char **)(fp->uf_def_args.ga_data))
[ai + fp->uf_def_args.ga_len];
- if (eval1(&default_expr, &def_rettv, true) == FAIL) {
+ if (eval1(&default_expr, &def_rettv, EVAL_EVALUATE) == FAIL) {
default_arg_err = true;
break;
}
@@ -1109,7 +1110,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
// A Lambda always has the command "return {expr}". It is much faster
// to evaluate {expr} directly.
ex_nesting_level++;
- (void)eval1(&p, rettv, true);
+ (void)eval1(&p, rettv, EVAL_EVALUATE);
ex_nesting_level--;
} else {
// call do_cmdline() to execute the lines
@@ -2953,7 +2954,7 @@ void ex_return(exarg_T *eap)
eap->nextcmd = NULL;
if ((*arg != NUL && *arg != '|' && *arg != '\n')
- && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) {
+ && eval0(arg, &rettv, &eap->nextcmd, eap->skip ? 0 : EVAL_EVALUATE) != FAIL) {
if (!eap->skip) {
returning = do_return(eap, false, true, &rettv);
} else {
@@ -3004,7 +3005,7 @@ void ex_call(exarg_T *eap)
// instead to skip to any following command, e.g. for:
// :if 0 | call dict.foo().bar() | endif.
emsg_skip++;
- if (eval0(eap->arg, &rettv, &eap->nextcmd, false) != FAIL) {
+ if (eval0(eap->arg, &rettv, &eap->nextcmd, 0) != FAIL) {
tv_clear(&rettv);
}
emsg_skip--;
@@ -3071,7 +3072,7 @@ void ex_call(exarg_T *eap)
}
// Handle a function returning a Funcref, Dictionary or List.
- if (handle_subscript((const char **)&arg, &rettv, true, true)
+ if (handle_subscript((const char **)&arg, &rettv, EVAL_EVALUATE, true)
== FAIL) {
failed = true;
break;
diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c
index 9120cc4471..a3dc0cfc04 100644
--- a/src/nvim/eval/vars.c
+++ b/src/nvim/eval/vars.c
@@ -175,21 +175,13 @@ static list_T *heredoc_get(exarg_T *eap, char *cmd)
/// ":let var ..= expr" assignment command.
/// ":let [var1, var2] = expr" unpack list.
/// ":let [name, ..., ; lastname] = expr" unpack list.
-void ex_let(exarg_T *eap)
-{
- ex_let_const(eap, false);
-}
-
+///
/// ":cons[t] var = expr1" define constant
/// ":cons[t] [name1, name2, ...] = expr1" define constants unpacking list
/// ":cons[t] [name, ..., ; lastname] = expr" define constants unpacking list
-void ex_const(exarg_T *eap)
-{
- ex_let_const(eap, true);
-}
-
-static void ex_let_const(exarg_T *eap, const bool is_const)
+void ex_let(exarg_T *eap)
{
+ const bool is_const = eap->cmdidx == CMD_const;
char *arg = eap->arg;
char *expr = NULL;
typval_T rettv;
@@ -208,8 +200,10 @@ static void ex_let_const(exarg_T *eap, const bool is_const)
argend--;
}
expr = skipwhite(argend);
- if (*expr != '=' && !((vim_strchr("+-*/%.", (uint8_t)(*expr)) != NULL
- && expr[1] == '=') || strncmp(expr, "..=", 3) == 0)) {
+ bool concat = strncmp(expr, "..=", 3) == 0;
+ bool has_assign = *expr == '=' || (vim_strchr("+-*/%.", (uint8_t)(*expr)) != NULL
+ && expr[1] == '=');
+ if (!has_assign && !concat) {
// ":let" without "=": list variables
if (*arg == '[') {
emsg(_(e_invarg));
@@ -240,6 +234,8 @@ static void ex_let_const(exarg_T *eap, const bool is_const)
tv_clear(&rettv);
}
} else {
+ rettv.v_type = VAR_UNKNOWN;
+
op[0] = '=';
op[1] = NUL;
if (*expr != '=') {
@@ -259,7 +255,8 @@ static void ex_let_const(exarg_T *eap, const bool is_const)
if (eap->skip) {
emsg_skip++;
}
- i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip);
+ int eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
+ i = eval0(expr, &rettv, &eap->nextcmd, eval_flags);
if (eap->skip) {
if (i != FAIL) {
tv_clear(&rettv);
@@ -506,7 +503,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first)
} else {
// handle d.key, l[idx], f(expr)
const char *const arg_subsc = arg;
- if (handle_subscript(&arg, &tv, true, true) == FAIL) {
+ if (handle_subscript(&arg, &tv, EVAL_EVALUATE, true) == FAIL) {
error = true;
} else {
if (arg == arg_subsc && len == 2 && name[1] == ':') {
@@ -1713,7 +1710,7 @@ bool var_exists(const char *var)
n = get_var_tv(name, len, &tv, NULL, false, true) == OK;
if (n) {
// Handle d.key, l[idx], f(expr).
- n = handle_subscript(&var, &tv, true, false) == OK;
+ n = handle_subscript(&var, &tv, EVAL_EVALUATE, false) == OK;
if (n) {
tv_clear(&tv);
}