0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.2.1794: no falsy Coalescing operator

Problem:    No falsy Coalescing operator.
Solution:   Add the "??" operator.  Fix mistake with function argument count.
This commit is contained in:
Bram Moolenaar
2020-10-03 20:17:30 +02:00
parent c8fe645c19
commit 92f26c256e
8 changed files with 257 additions and 97 deletions

View File

@@ -2110,6 +2110,7 @@ eval0(
/*
* Handle top level expression:
* expr2 ? expr1 : expr1
* expr2 ?? expr1
*
* "arg" must point to the first non-white of the expression.
* "arg" is advanced to just after the recognized expression.
@@ -2135,6 +2136,7 @@ eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
p = eval_next_non_blank(*arg, evalarg, &getnext);
if (*p == '?')
{
int op_falsy = p[1] == '?';
int result;
typval_T var2;
evalarg_T *evalarg_used = evalarg;
@@ -2168,11 +2170,12 @@ eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
{
int error = FALSE;
if (in_vim9script())
if (in_vim9script() || op_falsy)
result = tv2bool(rettv);
else if (tv_get_number_chk(rettv, &error) != 0)
result = TRUE;
clear_tv(rettv);
if (error || !op_falsy || !result)
clear_tv(rettv);
if (error)
return FAIL;
}
@@ -2180,6 +2183,8 @@ eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
/*
* Get the second variable. Recursive!
*/
if (op_falsy)
++*arg;
if (evaluate && in_vim9script() && !IS_WHITE_OR_NUL((*arg)[1]))
{
error_white_both(p, 1);
@@ -2187,62 +2192,67 @@ eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
return FAIL;
}
*arg = skipwhite_and_linebreak(*arg + 1, evalarg_used);
evalarg_used->eval_flags = result ? orig_flags
: orig_flags & ~EVAL_EVALUATE;
if (eval1(arg, rettv, evalarg_used) == FAIL)
evalarg_used->eval_flags = (op_falsy ? !result : result)
? orig_flags : orig_flags & ~EVAL_EVALUATE;
if (eval1(arg, &var2, evalarg_used) == FAIL)
{
evalarg_used->eval_flags = orig_flags;
return FAIL;
}
if (!op_falsy || !result)
*rettv = var2;
/*
* Check for the ":".
*/
p = eval_next_non_blank(*arg, evalarg_used, &getnext);
if (*p != ':')
if (!op_falsy)
{
emsg(_(e_missing_colon));
if (evaluate && result)
clear_tv(rettv);
evalarg_used->eval_flags = orig_flags;
return FAIL;
}
if (getnext)
*arg = eval_next_line(evalarg_used);
else
{
if (evaluate && in_vim9script() && !VIM_ISWHITE(p[-1]))
/*
* Check for the ":".
*/
p = eval_next_non_blank(*arg, evalarg_used, &getnext);
if (*p != ':')
{
emsg(_(e_missing_colon));
if (evaluate && result)
clear_tv(rettv);
evalarg_used->eval_flags = orig_flags;
return FAIL;
}
if (getnext)
*arg = eval_next_line(evalarg_used);
else
{
if (evaluate && in_vim9script() && !VIM_ISWHITE(p[-1]))
{
error_white_both(p, 1);
clear_tv(rettv);
evalarg_used->eval_flags = orig_flags;
return FAIL;
}
*arg = p;
}
/*
* Get the third variable. Recursive!
*/
if (evaluate && in_vim9script() && !IS_WHITE_OR_NUL((*arg)[1]))
{
error_white_both(p, 1);
clear_tv(rettv);
evalarg_used->eval_flags = orig_flags;
return FAIL;
}
*arg = p;
}
/*
* Get the third variable. Recursive!
*/
if (evaluate && in_vim9script() && !IS_WHITE_OR_NUL((*arg)[1]))
{
error_white_both(p, 1);
clear_tv(rettv);
evalarg_used->eval_flags = orig_flags;
return FAIL;
}
*arg = skipwhite_and_linebreak(*arg + 1, evalarg_used);
evalarg_used->eval_flags = !result ? orig_flags
*arg = skipwhite_and_linebreak(*arg + 1, evalarg_used);
evalarg_used->eval_flags = !result ? orig_flags
: orig_flags & ~EVAL_EVALUATE;
if (eval1(arg, &var2, evalarg_used) == FAIL)
{
if (evaluate && result)
clear_tv(rettv);
evalarg_used->eval_flags = orig_flags;
return FAIL;
if (eval1(arg, &var2, evalarg_used) == FAIL)
{
if (evaluate && result)
clear_tv(rettv);
evalarg_used->eval_flags = orig_flags;
return FAIL;
}
if (evaluate && !result)
*rettv = var2;
}
if (evaluate && !result)
*rettv = var2;
if (evalarg == NULL)
clear_evalarg(&local_evalarg, NULL);