changeset 21050:7a9daf73a724 v8.2.1076

patch 8.2.1076: Vim9: no line break allowed in :if expression Commit: https://github.com/vim/vim/commit/faf8626b79e380fe81e7ae2439a535ed7619d27b Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jun 27 23:07:36 2020 +0200 patch 8.2.1076: Vim9: no line break allowed in :if expression Problem: Vim9: no line break allowed in :if expression. Solution: Skip linebreak.
author Bram Moolenaar <Bram@vim.org>
date Sat, 27 Jun 2020 23:15:03 +0200
parents 4b256059a255
children 2cf2f56a250f
files src/eval.c src/evalvars.c src/proto/eval.pro src/testdir/test_vim9_cmd.vim src/version.c
diffstat 5 files changed, 73 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -166,10 +166,16 @@ eval_to_bool(
 {
     typval_T	tv;
     varnumber_T	retval = FALSE;
+    evalarg_T	evalarg;
+
+    CLEAR_FIELD(evalarg);
+    evalarg.eval_flags = skip ? 0 : EVAL_EVALUATE;
+    evalarg.eval_cookie = eap != NULL && eap->getline == getsourceline
+							  ? eap->cookie : NULL;
 
     if (skip)
 	++emsg_skip;
-    if (eval0(arg, &tv, eap, skip ? NULL : &EVALARG_EVALUATE) == FAIL)
+    if (eval0(arg, &tv, eap, &evalarg) == FAIL)
 	*error = TRUE;
     else
     {
@@ -182,6 +188,7 @@ eval_to_bool(
     }
     if (skip)
 	--emsg_skip;
+    clear_evalarg(&evalarg, eap);
 
     return (int)retval;
 }
@@ -1884,6 +1891,24 @@ skipwhite_and_linebreak(char_u *arg, eva
 }
 
 /*
+ * After using "evalarg" filled from "eap" free the memory.
+ */
+    void
+clear_evalarg(evalarg_T *evalarg, exarg_T *eap)
+{
+    if (evalarg != NULL && eap != NULL && evalarg->eval_tofree != NULL)
+    {
+	// We may need to keep the original command line, e.g. for
+	// ":let" it has the variable names.  But we may also need the
+	// new one, "nextcmd" points into it.  Keep both.
+	vim_free(eap->cmdline_tofree);
+	eap->cmdline_tofree = *eap->cmdlinep;
+	*eap->cmdlinep = evalarg->eval_tofree;
+	evalarg->eval_tofree = NULL;
+    }
+}
+
+/*
  * The "evaluate" argument: When FALSE, the argument is only parsed but not
  * executed.  The function may return OK, but the rettv will be of type
  * VAR_UNKNOWN.  The function still returns FAIL for a syntax error.
@@ -1934,16 +1959,7 @@ eval0(
     if (eap != NULL)
 	eap->nextcmd = check_nextcmd(p);
 
-    if (evalarg != NULL && eap != NULL && evalarg->eval_tofree != NULL)
-    {
-	// We may need to keep the original command line, e.g. for
-	// ":let" it has the variable names.  But we may also need the
-	// new one, "nextcmd" points into it.  Keep both.
-	vim_free(eap->cmdline_tofree);
-	eap->cmdline_tofree = *eap->cmdlinep;
-	*eap->cmdlinep = evalarg->eval_tofree;
-	evalarg->eval_tofree = NULL;
-    }
+    clear_evalarg(evalarg, eap);
 
     return ret;
 }
@@ -5223,6 +5239,7 @@ ex_echo(exarg_T *eap)
 	arg = skipwhite(arg);
     }
     eap->nextcmd = check_nextcmd(arg);
+    clear_evalarg(&evalarg, eap);
 
     if (eap->skip)
 	--emsg_skip;
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -804,7 +804,7 @@ ex_let(exarg_T *eap)
 	    i = eval0(expr, &rettv, eap, &evalarg);
 	    if (eap->skip)
 		--emsg_skip;
-	    vim_free(evalarg.eval_tofree);
+	    clear_evalarg(&evalarg, eap);
 	}
 	if (eap->skip)
 	{
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -30,6 +30,7 @@ int pattern_match(char_u *pat, char_u *t
 char_u *eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext);
 char_u *eval_next_line(evalarg_T *evalarg);
 char_u *skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg);
+void clear_evalarg(evalarg_T *evalarg, exarg_T *eap);
 int eval0(char_u *arg, typval_T *rettv, exarg_T *eap, evalarg_T *evalarg);
 int eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
 void eval_addblob(typval_T *tv1, typval_T *tv2);
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -101,5 +101,46 @@ def Test_echo_linebreak()
   CheckScriptSuccess(lines)
 enddef
 
+def Test_if_linebreak()
+  let lines =<< trim END
+      vim9script
+      if 1 &&
+            2
+            || 3
+        g:res = 42
+      endif
+      assert_equal(42, g:res)
+  END
+  CheckScriptSuccess(lines)
+  unlet g:res
+
+  lines =<< trim END
+      vim9script
+      if 1 &&
+            0
+        g:res = 0
+      elseif 0 ||
+              0
+              || 1
+        g:res = 12
+      endif
+      assert_equal(12, g:res)
+  END
+  CheckScriptSuccess(lines)
+  unlet g:res
+enddef
+
+def Test_while_linebreak()
+  " TODO: line break in :while expression doesn't work yet
+  let lines =<< trim END
+      vim9script
+      let nr = 0
+      while nr < 10 + 3
+            nr = nr + 4
+      endwhile
+      assert_equal(16, nr)
+  END
+  CheckScriptSuccess(lines)
+enddef
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1076,
+/**/
     1075,
 /**/
     1074,