# HG changeset patch # User Bram Moolenaar # Date 1580505303 -3600 # Node ID 77cce043971402c03f8a1d49d580b638ceda5c8e # Parent 9526505873326fd537ffdc5a9385454ecd7ec1c2 patch 8.2.0188: Check commands don't work well with Vim9 script Commit: https://github.com/vim/vim/commit/7f829cab356d63b8e59559285593777a66bcc02b Author: Bram Moolenaar Date: Fri Jan 31 22:12:41 2020 +0100 patch 8.2.0188: Check commands don't work well with Vim9 script Problem: Check commands don't work well with Vim9 script. Solution: Improve constant expression handling. diff --git a/src/testdir/check.vim b/src/testdir/check.vim --- a/src/testdir/check.vim +++ b/src/testdir/check.vim @@ -1,10 +1,12 @@ source shared.vim +command -nargs=1 MissingFeature throw 'Skipped: ' .. .. ' feature missing' + " Command to check for the presence of a feature. command -nargs=1 CheckFeature call CheckFeature() func CheckFeature(name) if !has(a:name) - throw 'Skipped: ' .. a:name .. ' feature missing' + MissingFeature a:name endif endfunc diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -31,7 +31,9 @@ def Test_expr1() assert_equal('two', false ? 'one' : 'two') assert_equal('two', 0 ? 'one' : 'two') - assert_equal('two', 0.0 ? 'one' : 'two') + if has('float') + assert_equal('two', 0.0 ? 'one' : 'two') + endif assert_equal('two', '' ? 'one' : 'two') " assert_equal('one', 0z ? 'one' : 'two') assert_equal('two', [] ? 'one' : 'two') @@ -420,22 +422,25 @@ def Test_expr5() enddef def Test_expr5_float() - CheckFeature float - assert_equal(66.0, 60.0 + 6.0) - assert_equal(66.0, 60.0 + 6) - assert_equal(66.0, 60 + 6.0) - assert_equal(5.1, g:afloat + 5) - assert_equal(8.1, 8 + g:afloat) - assert_equal(10.1, g:anint + g:afloat) - assert_equal(10.1, g:afloat + g:anint) + if !has('float') + MissingFeature 'float' + else + assert_equal(66.0, 60.0 + 6.0) + assert_equal(66.0, 60.0 + 6) + assert_equal(66.0, 60 + 6.0) + assert_equal(5.1, g:afloat + 5) + assert_equal(8.1, 8 + g:afloat) + assert_equal(10.1, g:anint + g:afloat) + assert_equal(10.1, g:afloat + g:anint) - assert_equal(54.0, 60.0 - 6.0) - assert_equal(54.0, 60.0 - 6) - assert_equal(54.0, 60 - 6.0) - assert_equal(-4.9, g:afloat - 5) - assert_equal(7.9, 8 - g:afloat) - assert_equal(9.9, g:anint - g:afloat) - assert_equal(-9.9, g:afloat - g:anint) + assert_equal(54.0, 60.0 - 6.0) + assert_equal(54.0, 60.0 - 6) + assert_equal(54.0, 60 - 6.0) + assert_equal(-4.9, g:afloat - 5) + assert_equal(7.9, 8 - g:afloat) + assert_equal(9.9, g:anint - g:afloat) + assert_equal(-9.9, g:afloat - g:anint) + endif enddef func Test_expr5_fails() @@ -476,27 +481,29 @@ def Test_expr6() enddef def Test_expr6_float() - CheckFeature float - - assert_equal(36.0, 6.0 * 6) - assert_equal(36.0, 6 * 6.0) - assert_equal(36.0, 6.0 * 6.0) - assert_equal(1.0, g:afloat * g:anint) + if !has('float') + MissingFeature 'float' + else + assert_equal(36.0, 6.0 * 6) + assert_equal(36.0, 6 * 6.0) + assert_equal(36.0, 6.0 * 6.0) + assert_equal(1.0, g:afloat * g:anint) - assert_equal(10.0, 60 / 6.0) - assert_equal(10.0, 60.0 / 6) - assert_equal(10.0, 60.0 / 6.0) - assert_equal(0.01, g:afloat / g:anint) + assert_equal(10.0, 60 / 6.0) + assert_equal(10.0, 60.0 / 6) + assert_equal(10.0, 60.0 / 6.0) + assert_equal(0.01, g:afloat / g:anint) - assert_equal(4.0, 6.0 * 4 / 6) - assert_equal(4.0, 6 * 4.0 / 6) - assert_equal(4.0, 6 * 4 / 6.0) - assert_equal(4.0, 6.0 * 4.0 / 6) - assert_equal(4.0, 6 * 4.0 / 6.0) - assert_equal(4.0, 6.0 * 4 / 6.0) - assert_equal(4.0, 6.0 * 4.0 / 6.0) + assert_equal(4.0, 6.0 * 4 / 6) + assert_equal(4.0, 6 * 4.0 / 6) + assert_equal(4.0, 6 * 4 / 6.0) + assert_equal(4.0, 6.0 * 4.0 / 6) + assert_equal(4.0, 6 * 4.0 / 6.0) + assert_equal(4.0, 6.0 * 4 / 6.0) + assert_equal(4.0, 6.0 * 4.0 / 6.0) - assert_equal(4.0, 6.0 * 4.0 / 6.0) + assert_equal(4.0, 6.0 * 4.0 / 6.0) + endif enddef func Test_expr6_fails() @@ -581,7 +588,9 @@ enddef def Test_expr7_float() " float constant - if has('float') + if !has('float') + MissingFeature 'float' + else assert_equal(g:float_zero, .0) assert_equal(g:float_zero, 0.0) assert_equal(g:float_neg, -9.8) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 188, +/**/ 187, /**/ 186, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -3460,14 +3460,31 @@ new_scope(cctx_T *cctx, scopetype_T type } /* - * Evaluate an expression that is a constant: has(arg) + * Evaluate an expression that is a constant: + * has(arg) + * + * Also handle: + * ! in front logical NOT + * * Return FAIL if the expression is not a constant. */ static int -evaluate_const_expr4(char_u **arg, cctx_T *cctx UNUSED, typval_T *tv) +evaluate_const_expr7(char_u **arg, cctx_T *cctx UNUSED, typval_T *tv) { typval_T argvars[2]; - + char_u *start_leader, *end_leader; + + /* + * Skip '!' characters. They are handled later. + */ + start_leader = *arg; + while (**arg == '!') + *arg = skipwhite(*arg + 1); + end_leader = *arg; + + /* + * Recognize only has() for now. + */ if (STRNCMP("has(", *arg, 4) != 0) return FAIL; *arg = skipwhite(*arg + 4); @@ -3497,6 +3514,13 @@ evaluate_const_expr4(char_u **arg, cctx_ f_has(argvars, tv); clear_tv(&argvars[0]); + while (start_leader < end_leader) + { + if (*start_leader == '!') + tv->vval.v_number = !tv->vval.v_number; + ++start_leader; + } + return OK; } @@ -3529,7 +3553,7 @@ evaluate_const_and_or(char_u **arg, cctx *arg = skipwhite(p + 2); tv2.v_type = VAR_UNKNOWN; if ((opchar == '|' ? evaluate_const_expr3(arg, cctx, &tv2) - : evaluate_const_expr4(arg, cctx, &tv2)) == FAIL) + : evaluate_const_expr7(arg, cctx, &tv2)) == FAIL) { clear_tv(&tv2); return FAIL; @@ -3558,7 +3582,7 @@ evaluate_const_and_or(char_u **arg, cctx evaluate_const_expr3(char_u **arg, cctx_T *cctx, typval_T *tv) { // evaluate the first expression - if (evaluate_const_expr4(arg, cctx, tv) == FAIL) + if (evaluate_const_expr7(arg, cctx, tv) == FAIL) return FAIL; // || and && work almost the same