]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.0188: Check commands don't work well with Vim9 script v8.2.0188
authorBram Moolenaar <Bram@vim.org>
Fri, 31 Jan 2020 21:12:41 +0000 (22:12 +0100)
committerBram Moolenaar <Bram@vim.org>
Fri, 31 Jan 2020 21:12:41 +0000 (22:12 +0100)
Problem:    Check commands don't work well with Vim9 script.
Solution:   Improve constant expression handling.

src/testdir/check.vim
src/testdir/test_vim9_expr.vim
src/version.c
src/vim9compile.c

index 30c415821ffeb3ede7f41cd9dbcaf25f19d2c95d..6efa348e5ad29671da4f909eb6c0faab6c3b1520 100644 (file)
@@ -1,10 +1,12 @@
 source shared.vim
 
+command -nargs=1 MissingFeature throw 'Skipped: ' .. <args> .. ' feature missing'
+
 " Command to check for the presence of a feature.
 command -nargs=1 CheckFeature call CheckFeature(<f-args>)
 func CheckFeature(name)
   if !has(a:name)
-    throw 'Skipped: ' .. a:name .. ' feature missing'
+    MissingFeature a:name
   endif
 endfunc
 
index e66a559efe1b5a0eca27a3a6b9af760adbdc0016..1ff713126bd66cf84f5e76f58fa8e8238eb311e2 100644 (file)
@@ -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)
-
-  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)
+  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)
+  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)
-
-  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.0 / 6.0)
+  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(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)
+  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)
index f4022c6d8a57803e08d5935c3e5ad2bd974dd59b..9a3d42f0b95972b7809e9a76f991ef1d53e09bb1 100644 (file)
@@ -742,6 +742,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    188,
 /**/
     187,
 /**/
index fe836487ba4deb8414b597137cc8aa0318f0a9ea..651c5ba92dfbbbad2010f13a6a2a1ccc660c0ede 100644 (file)
@@ -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_T *cctx UNUSED, typval_T *tv)
     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_T *cctx, char *op, typval_T *tv)
            *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_T *cctx, char *op, typval_T *tv)
 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