changeset 20407:33166d945b54 v8.2.0758

patch 8.2.0758: Vim9: no test for STORELIST and STOREDICT Commit: https://github.com/vim/vim/commit/cb7904016eb817e80760c394044740df8273c774 Author: Bram Moolenaar <Bram@vim.org> Date: Fri May 15 20:53:00 2020 +0200 patch 8.2.0758: Vim9: no test for STORELIST and STOREDICT Problem: Vim9: no test for STORELIST and STOREDICT. Solution: Add a test. Make matches stricter.
author Bram Moolenaar <Bram@vim.org>
date Fri, 15 May 2020 21:00:03 +0200
parents 58bcb71172b7
children f56e1311790e
files src/testdir/test_vim9_disassemble.vim src/version.c
diffstat 2 files changed, 263 insertions(+), 189 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -154,6 +154,37 @@ def Test_disassemble_store()
         res)
 enddef
 
+def s:ScriptFuncStoreMember()
+  let locallist: list<number> = []
+  locallist[0] = 123
+  let localdict: dict<number> = {}
+  localdict["a"] = 456
+enddef
+
+def Test_disassemble_store_member()
+  let res = execute('disass s:ScriptFuncStoreMember')
+  assert_match('<SNR>\d*_ScriptFuncStoreMember\_s*' ..
+        'let locallist: list<number> = []\_s*' ..
+        '\d NEWLIST size 0\_s*' ..
+        '\d STORE $0\_s*' ..
+        'locallist\[0\] = 123\_s*' ..
+        '\d PUSHNR 123\_s*' ..
+        '\d PUSHNR 0\_s*' ..
+        '\d LOAD $0\_s*' ..
+        '\d STORELIST\_s*' ..
+        'let localdict: dict<number> = {}\_s*' ..
+        '\d NEWDICT size 0\_s*' ..
+        '\d STORE $1\_s*' ..
+        'localdict\["a"\] = 456\_s*' ..
+        '\d\+ PUSHNR 456\_s*' ..
+        '\d\+ PUSHS "a"\_s*' ..
+        '\d\+ LOAD $1\_s*' ..
+        '\d\+ STOREDICT\_s*' ..
+        '\d\+ PUSHNR 0\_s*' ..
+        '\d\+ RETURN',
+        res)
+enddef
+
 def s:ScriptFuncUnlet()
   g:somevar = "value"
   unlet g:somevar
@@ -163,46 +194,53 @@ enddef
 
 def Test_disassemble_unlet()
   let res = execute('disass s:ScriptFuncUnlet')
-  assert_match('<SNR>\d*_ScriptFuncUnlet.*' ..
-        'g:somevar = "value".*' ..
-        '\d PUSHS "value".*' ..
-        '\d STOREG g:somevar.*' ..
-        'unlet g:somevar.*' ..
-        '\d UNLET g:somevar.*' ..
-        'unlet! g:somevar.*' ..
-        '\d UNLET! g:somevar.*' ..
-        'unlet $SOMEVAR.*' ..
-        '\d UNLETENV $SOMEVAR.*',
+  assert_match('<SNR>\d*_ScriptFuncUnlet\_s*' ..
+        'g:somevar = "value"\_s*' ..
+        '\d PUSHS "value"\_s*' ..
+        '\d STOREG g:somevar\_s*' ..
+        'unlet g:somevar\_s*' ..
+        '\d UNLET g:somevar\_s*' ..
+        'unlet! g:somevar\_s*' ..
+        '\d UNLET! g:somevar\_s*' ..
+        'unlet $SOMEVAR\_s*' ..
+        '\d UNLETENV $SOMEVAR\_s*',
         res)
 enddef
 
 def s:ScriptFuncTry()
   try
-    echo 'yes'
+    echo "yes"
   catch /fail/
-    echo 'no'
+    echo "no"
   finally
-    throw 'end'
+    throw "end"
   endtry
 enddef
 
 def Test_disassemble_try()
   let res = execute('disass s:ScriptFuncTry')
-  assert_match('<SNR>\d*_ScriptFuncTry.*' ..
-        'try.*' ..
-        'TRY catch -> \d\+, finally -> \d\+.*' ..
-        'catch /fail/.*' ..
-        ' JUMP -> \d\+.*' ..
-        ' PUSH v:exception.*' ..
-        ' PUSHS "fail".*' ..
-        ' COMPARESTRING =\~.*' ..
-        ' JUMP_IF_FALSE -> \d\+.*' ..
-        ' CATCH.*' ..
-        'finally.*' ..
-        ' PUSHS "end".*' ..
-        ' THROW.*' ..
-        'endtry.*' ..
-        ' ENDTRY.*',
+  assert_match('<SNR>\d*_ScriptFuncTry\_s*' ..
+        'try\_s*' ..
+        '\d TRY catch -> \d\+, finally -> \d\+\_s*' ..
+        'echo "yes"\_s*' ..
+        '\d PUSHS "yes"\_s*' ..
+        '\d ECHO 1\_s*' ..
+        'catch /fail/\_s*' ..
+        '\d JUMP -> \d\+\_s*' ..
+        '\d PUSH v:exception\_s*' ..
+        '\d PUSHS "fail"\_s*' ..
+        '\d COMPARESTRING =\~\_s*' ..
+        '\d JUMP_IF_FALSE -> \d\+\_s*' ..
+        '\d CATCH\_s*' ..
+        'echo "no"\_s*' ..
+        '\d\+ PUSHS "no"\_s*' ..
+        '\d\+ ECHO 1\_s*' ..
+        'finally\_s*' ..
+        'throw "end"\_s*' ..
+        '\d\+ PUSHS "end"\_s*' ..
+        '\d\+ THROW\_s*' ..
+        'endtry\_s*' ..
+        '\d\+ ENDTRY',
         res)
 enddef
 
@@ -213,18 +251,19 @@ enddef
 
 def Test_disassemble_new()
   let res = execute('disass s:ScriptFuncNew')
-  assert_match('<SNR>\d*_ScriptFuncNew.*' ..
-        'let ll = \[1, "two", 333].*' ..
-        'PUSHNR 1.*' ..
-        'PUSHS "two".*' ..
-        'PUSHNR 333.*' ..
-        'NEWLIST size 3.*' ..
-        'let dd = #{one: 1, two: "val"}.*' ..
-        'PUSHS "one".*' ..
-        'PUSHNR 1.*' ..
-        'PUSHS "two".*' ..
-        'PUSHS "val".*' ..
-        'NEWDICT size 2.*',
+  assert_match('<SNR>\d*_ScriptFuncNew\_s*' ..
+        'let ll = \[1, "two", 333\]\_s*' ..
+        '\d PUSHNR 1\_s*' ..
+        '\d PUSHS "two"\_s*' ..
+        '\d PUSHNR 333\_s*' ..
+        '\d NEWLIST size 3\_s*' ..
+        '\d STORE $0\_s*' ..
+        'let dd = #{one: 1, two: "val"}\_s*' ..
+        '\d PUSHS "one"\_s*' ..
+        '\d PUSHNR 1\_s*' ..
+        '\d PUSHS "two"\_s*' ..
+        '\d PUSHS "val"\_s*' ..
+        '\d NEWDICT size 2\_s*',
         res)
 enddef
 
@@ -258,38 +297,54 @@ enddef
 
 def Test_disassemble_call()
   let res = execute('disass s:ScriptFuncCall')
-  assert_match('<SNR>\d\+_ScriptFuncCall.*' ..
-        'changenr().*' ..
-        ' BCALL changenr(argc 0).*' ..
-        'char2nr("abc").*' ..
-        ' PUSHS "abc".*' ..
-        ' BCALL char2nr(argc 1).*' ..
-        'Test_disassemble_new().*' ..
-        ' DCALL Test_disassemble_new(argc 0).*' ..
-        'FuncWithArg(343).*' ..
-        ' PUSHNR 343.*' ..
-        ' DCALL FuncWithArg(argc 1).*' ..
-        'ScriptFuncNew().*' ..
-        ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
-        's:ScriptFuncNew().*' ..
-        ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
-        'UserFunc().*' ..
-        ' UCALL UserFunc(argc 0).*' ..
-        'UserFuncWithArg("foo").*' ..
-        ' PUSHS "foo".*' ..
-        ' UCALL UserFuncWithArg(argc 1).*' ..
-        'let FuncRef = function("UserFunc").*' ..
-        'FuncRef().*' ..
-        ' LOAD $\d.*' ..
-        ' PCALL (argc 0).*' ..
-        'let FuncRefWithArg = function("UserFuncWithArg").*' ..
-        'FuncRefWithArg("bar").*' ..
-        ' PUSHS "bar".*' ..
-        ' LOAD $\d.*' ..
-        ' PCALL (argc 1).*' ..
-        'return "yes".*' ..
-        ' PUSHS "yes".*' ..
-        ' RETURN.*',
+  assert_match('<SNR>\d\+_ScriptFuncCall\_s*' ..
+        'changenr()\_s*' ..
+        '\d BCALL changenr(argc 0)\_s*' ..
+        '\d DROP\_s*' ..
+        'char2nr("abc")\_s*' ..
+        '\d PUSHS "abc"\_s*' ..
+        '\d BCALL char2nr(argc 1)\_s*' ..
+        '\d DROP\_s*' ..
+        'Test_disassemble_new()\_s*' ..
+        '\d DCALL Test_disassemble_new(argc 0)\_s*' ..
+        '\d DROP\_s*' ..
+        'FuncWithArg(343)\_s*' ..
+        '\d\+ PUSHNR 343\_s*' ..
+        '\d\+ DCALL FuncWithArg(argc 1)\_s*' ..
+        '\d\+ DROP\_s*' ..
+        'ScriptFuncNew()\_s*' ..
+        '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
+        '\d\+ DROP\_s*' ..
+        's:ScriptFuncNew()\_s*' ..
+        '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
+        '\d\+ DROP\_s*' ..
+        'UserFunc()\_s*' ..
+        '\d\+ UCALL UserFunc(argc 0)\_s*' ..
+        '\d\+ DROP\_s*' ..
+        'UserFuncWithArg("foo")\_s*' ..
+        '\d\+ PUSHS "foo"\_s*' ..
+        '\d\+ UCALL UserFuncWithArg(argc 1)\_s*' ..
+        '\d\+ DROP\_s*' ..
+        'let FuncRef = function("UserFunc")\_s*' ..
+        '\d\+ PUSHS "UserFunc"\_s*' ..
+        '\d\+ BCALL function(argc 1)\_s*' ..
+        '\d\+ STORE $0\_s*' ..
+        'FuncRef()\_s*' ..
+        '\d\+ LOAD $\d\_s*' ..
+        '\d\+ PCALL (argc 0)\_s*' ..
+        '\d\+ DROP\_s*' ..
+        'let FuncRefWithArg = function("UserFuncWithArg")\_s*' ..
+        '\d\+ PUSHS "UserFuncWithArg"\_s*' ..
+        '\d\+ BCALL function(argc 1)\_s*' ..
+        '\d\+ STORE $1\_s*' ..
+        'FuncRefWithArg("bar")\_s*' ..
+        '\d\+ PUSHS "bar"\_s*' ..
+        '\d\+ LOAD $\d\_s*' ..
+        '\d\+ PCALL (argc 1)\_s*' ..
+        '\d\+ DROP\_s*' ..
+        'return "yes"\_s*' ..
+        '\d\+ PUSHS "yes"\_s*' ..
+        '\d\+ RETURN',
         res)
 enddef
 
@@ -308,21 +363,21 @@ enddef
 def Test_disassemble_closure()
   CreateRefs()
   let res = execute('disass g:Append')
-  assert_match('<lambda>\d.*' ..
-        'local ..= arg.*' ..
-        '\d LOADOUTER $0.*' ..
-        '\d LOAD arg\[-1\].*' ..
-        '\d CONCAT.*' ..
-        '\d STOREOUTER $0.*' ..
-        '\d PUSHNR 0.*' ..
-        '\d RETURN.*',
+  assert_match('<lambda>\d\_s*' ..
+        'local ..= arg\_s*' ..
+        '\d LOADOUTER $0\_s*' ..
+        '\d LOAD arg\[-1\]\_s*' ..
+        '\d CONCAT\_s*' ..
+        '\d STOREOUTER $0\_s*' ..
+        '\d PUSHNR 0\_s*' ..
+        '\d RETURN',
         res)
 
   res = execute('disass g:Get')
-  assert_match('<lambda>\d.*' ..
-        'return local.*' ..
-        '\d LOADOUTER $0.*' ..
-        '\d RETURN.*',
+  assert_match('<lambda>\d\_s*' ..
+        'return local\_s*' ..
+        '\d LOADOUTER $0\_s*' ..
+        '\d RETURN',
         res)
 
   unlet g:Append
@@ -342,15 +397,15 @@ enddef
 
 def Test_disassemble_pcall()
   let res = execute('disass s:ScriptPCall')
-  assert_match('<SNR>\d\+_ScriptPCall.*' ..
-        'RefThis()("text").*' ..
-        '\d DCALL RefThis(argc 0).*' ..
-        '\d PUSHS "text".*' ..
-        '\d PCALL top (argc 1).*' ..
-        '\d PCALL end.*' ..
-        '\d DROP.*' ..
-        '\d PUSHNR 0.*' ..
-        '\d RETURN.*',
+  assert_match('<SNR>\d\+_ScriptPCall\_s*' ..
+        'RefThis()("text")\_s*' ..
+        '\d DCALL RefThis(argc 0)\_s*' ..
+        '\d PUSHS "text"\_s*' ..
+        '\d PCALL top (argc 1)\_s*' ..
+        '\d PCALL end\_s*' ..
+        '\d DROP\_s*' ..
+        '\d PUSHNR 0\_s*' ..
+        '\d RETURN',
         res)
 enddef
 
@@ -365,24 +420,24 @@ enddef
 
 def Test_disassemble_update_instr()
   let res = execute('disass s:FuncWithForwardCall')
-  assert_match('FuncWithForwardCall.*' ..
-        'return g:DefinedLater("yes").*' ..
-        '\d PUSHS "yes".*' ..
-        '\d UCALL g:DefinedLater(argc 1).*' ..
-        '\d CHECKTYPE string stack\[-1].*' ..
-        '\d RETURN.*',
+  assert_match('FuncWithForwardCall\_s*' ..
+        'return g:DefinedLater("yes")\_s*' ..
+        '\d PUSHS "yes"\_s*' ..
+        '\d UCALL g:DefinedLater(argc 1)\_s*' ..
+        '\d CHECKTYPE string stack\[-1]\_s*' ..
+        '\d RETURN',
         res)
 
   " Calling the function will change UCALL into the faster DCALL
   assert_equal('yes', FuncWithForwardCall())
 
   res = execute('disass s:FuncWithForwardCall')
-  assert_match('FuncWithForwardCall.*' ..
-        'return g:DefinedLater("yes").*' ..
-        '\d PUSHS "yes".*' ..
-        '\d DCALL DefinedLater(argc 1).*' ..
-        '\d CHECKTYPE string stack\[-1].*' ..
-        '\d RETURN.*',
+  assert_match('FuncWithForwardCall\_s*' ..
+        'return g:DefinedLater("yes")\_s*' ..
+        '\d PUSHS "yes"\_s*' ..
+        '\d DCALL DefinedLater(argc 1)\_s*' ..
+        '\d CHECKTYPE string stack\[-1]\_s*' ..
+        '\d RETURN',
         res)
 enddef
 
@@ -393,12 +448,12 @@ enddef
 
 def Test_disassemble_call_default()
   let res = execute('disass FuncWithDefault')
-  assert_match('FuncWithDefault.*' ..
-        '\d PUSHS "default".*' ..
-        '\d STORE arg\[-1].*' ..
-        'return arg.*' ..
-        '\d LOAD arg\[-1].*' ..
-        '\d RETURN.*',
+  assert_match('FuncWithDefault\_s*' ..
+        '\d PUSHS "default"\_s*' ..
+        '\d STORE arg\[-1]\_s*' ..
+        'return arg\_s*' ..
+        '\d LOAD arg\[-1]\_s*' ..
+        '\d RETURN',
         res)
 enddef
 
@@ -434,18 +489,27 @@ enddef
 def Test_disassemble_const_expr()
   assert_equal("\nyes", execute('call HasEval()'))
   let instr = execute('disassemble HasEval')
-  assert_match('HasEval.*' ..
-        'if has("eval").*' ..
-        ' PUSHS "yes".*',
+  assert_match('HasEval\_s*' ..
+        'if has("eval")\_s*' ..
+        'echo "yes"\_s*' ..
+        '\d PUSHS "yes"\_s*' ..
+        '\d ECHO 1\_s*' ..
+        'else\_s*' ..
+        'echo "no"\_s*' ..
+        'endif\_s*',
         instr)
   assert_notmatch('JUMP', instr)
 
   assert_equal("\nno", execute('call HasNothing()'))
   instr = execute('disassemble HasNothing')
-  assert_match('HasNothing.*' ..
-        'if has("nothing").*' ..
-        'else.*' ..
-        ' PUSHS "no".*',
+  assert_match('HasNothing\_s*' ..
+        'if has("nothing")\_s*' ..
+        'echo "yes"\_s*' ..
+        'else\_s*' ..
+        'echo "no"\_s*' ..
+        '\d PUSHS "no"\_s*' ..
+        '\d ECHO 1\_s*' ..
+        'endif',
         instr)
   assert_notmatch('PUSHS "yes"', instr)
   assert_notmatch('JUMP', instr)
@@ -453,11 +517,17 @@ def Test_disassemble_const_expr()
   assert_equal("\neval", execute('call HasSomething()'))
   instr = execute('disassemble HasSomething')
   assert_match('HasSomething.*' ..
-        'if has("nothing").*' ..
-        'elseif has("something").*' ..
-        'elseif has("eval").*' ..
-        ' PUSHS "eval".*' ..
-        'elseif has("less").*',
+        'if has("nothing")\_s*' ..
+        'echo "nothing"\_s*' ..
+        'elseif has("something")\_s*' ..
+        'echo "something"\_s*' ..
+        'elseif has("eval")\_s*' ..
+        'echo "eval"\_s*' ..
+        '\d PUSHS "eval"\_s*' ..
+        '\d ECHO 1\_s*' ..
+        'elseif has("less").*' ..
+        'echo "less"\_s*' ..
+        'endif',
         instr)
   assert_notmatch('PUSHS "nothing"', instr)
   assert_notmatch('PUSHS "something"', instr)
@@ -473,20 +543,20 @@ enddef
 
 def Test_disassemble_function()
   let instr = execute('disassemble WithFunc')
-  assert_match('WithFunc.*' ..
-        'let Funky1: func.*' ..
-        '0 PUSHFUNC "\[none]".*' ..
-        '1 STORE $0.*' ..
-        'let Funky2: func = function("len").*' ..
-        '2 PUSHS "len".*' ..
-        '3 BCALL function(argc 1).*' ..
-        '4 STORE $1.*' ..
-        'let Party2: func = funcref("UserFunc").*' ..
-        '\d PUSHS "UserFunc".*' ..
-        '\d BCALL funcref(argc 1).*' ..
-        '\d STORE $2.*' ..
-        '\d PUSHNR 0.*' ..
-        '\d RETURN.*',
+  assert_match('WithFunc\_s*' ..
+        'let Funky1: func\_s*' ..
+        '0 PUSHFUNC "\[none]"\_s*' ..
+        '1 STORE $0\_s*' ..
+        'let Funky2: func = function("len")\_s*' ..
+        '2 PUSHS "len"\_s*' ..
+        '3 BCALL function(argc 1)\_s*' ..
+        '4 STORE $1\_s*' ..
+        'let Party2: func = funcref("UserFunc")\_s*' ..
+        '\d PUSHS "UserFunc"\_s*' ..
+        '\d BCALL funcref(argc 1)\_s*' ..
+        '\d STORE $2\_s*' ..
+        '\d PUSHNR 0\_s*' ..
+        '\d RETURN',
         instr)
 enddef
 
@@ -502,19 +572,19 @@ def Test_disassemble_channel()
   CheckFeature channel
 
   let instr = execute('disassemble WithChannel')
-  assert_match('WithChannel.*' ..
-        'let job1: job.*' ..
-        '\d PUSHJOB "no process".*' ..
-        '\d STORE $0.*' ..
-        'let job2: job = job_start("donothing").*' ..
-        '\d PUSHS "donothing".*' ..
-        '\d BCALL job_start(argc 1).*' ..
-        '\d STORE $1.*' ..
-        'let chan1: channel.*' ..
-        '\d PUSHCHANNEL 0.*' ..
-        '\d STORE $2.*' ..
-        '\d PUSHNR 0.*' ..
-        '\d RETURN.*',
+  assert_match('WithChannel\_s*' ..
+        'let job1: job\_s*' ..
+        '\d PUSHJOB "no process"\_s*' ..
+        '\d STORE $0\_s*' ..
+        'let job2: job = job_start("donothing")\_s*' ..
+        '\d PUSHS "donothing"\_s*' ..
+        '\d BCALL job_start(argc 1)\_s*' ..
+        '\d STORE $1\_s*' ..
+        'let chan1: channel\_s*' ..
+        '\d PUSHCHANNEL 0\_s*' ..
+        '\d STORE $2\_s*' ..
+        '\d PUSHNR 0\_s*' ..
+        '\d RETURN',
         instr)
 enddef
 
@@ -526,13 +596,15 @@ enddef
 def Test_disassemble_lambda()
   assert_equal("XxX", WithLambda())
   let instr = execute('disassemble WithLambda')
-  assert_match('WithLambda.*' ..
-        'let F = {a -> "X" .. a .. "X"}.*' ..
-        ' FUNCREF <lambda>\d\+.*' ..
-        'PUSHS "x".*' ..
-        ' LOAD $0.*' ..
-        ' PCALL (argc 1).*' ..
-        ' CHECKTYPE string stack\[-1].*',
+  assert_match('WithLambda\_s*' ..
+        'let F = {a -> "X" .. a .. "X"}\_s*' ..
+        '\d FUNCREF <lambda>\d\+ $1\_s*' ..
+        '\d STORE $0\_s*' ..
+        'return F("x")\_s*' ..
+        '\d PUSHS "x"\_s*' ..
+        '\d LOAD $0\_s*' ..
+        '\d PCALL (argc 1)\_s*' ..
+        '\d CHECKTYPE string stack\[-1]',
         instr)
 enddef
 
@@ -548,20 +620,20 @@ def Test_disassemble_and_or()
   assert_equal("no", AndOr(2))
   assert_equal("yes", AndOr(4))
   let instr = execute('disassemble AndOr')
-  assert_match('AndOr.*' ..
-        'if arg == 1 && arg != 2 || arg == 4.*' ..
-        '\d LOAD arg\[-1].*' ..
-        '\d PUSHNR 1.*' ..
-        '\d COMPAREANY ==.*' ..
-        '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*' ..
-        '\d LOAD arg\[-1].*' ..
-        '\d PUSHNR 2.*' ..
-        '\d COMPAREANY !=.*' ..
-        '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*' ..
-        '\d LOAD arg\[-1].*' ..
-        '\d PUSHNR 4.*' ..
-        '\d COMPAREANY ==.*' ..
-        '\d JUMP_IF_FALSE -> \d\+.*',
+  assert_match('AndOr\_s*' ..
+        'if arg == 1 && arg != 2 || arg == 4\_s*' ..
+        '\d LOAD arg\[-1]\_s*' ..
+        '\d PUSHNR 1\_s*' ..
+        '\d COMPAREANY ==\_s*' ..
+        '\d JUMP_AND_KEEP_IF_FALSE -> \d\+\_s*' ..
+        '\d LOAD arg\[-1]\_s*' ..
+        '\d PUSHNR 2\_s*' ..
+        '\d COMPAREANY !=\_s*' ..
+        '\d JUMP_AND_KEEP_IF_TRUE -> \d\+\_s*' ..
+        '\d LOAD arg\[-1]\_s*' ..
+        '\d\+ PUSHNR 4\_s*' ..
+        '\d\+ COMPAREANY ==\_s*' ..
+        '\d\+ JUMP_IF_FALSE -> \d\+',
         instr)
 enddef
 
@@ -576,24 +648,24 @@ enddef
 def Test_disassemble_for_loop()
   assert_equal([0, 1, 2], ForLoop())
   let instr = execute('disassemble ForLoop')
-  assert_match('ForLoop.*' ..
-        'let res: list<number>.*' ..
-        ' NEWLIST size 0.*' ..
-        '\d STORE $0.*' ..
-        'for i in range(3).*' ..
-        '\d STORE -1 in $1.*' ..
-        '\d PUSHNR 3.*' ..
-        '\d BCALL range(argc 1).*' ..
-        '\d FOR $1 -> \d\+.*' ..
-        '\d STORE $2.*' ..
-        'res->add(i).*' ..
-        '\d LOAD $0.*' ..
-        '\d LOAD $2.*' ..
-        '\d BCALL add(argc 2).*' ..
-        '\d DROP.*' ..
-        'endfor.*' ..
-        '\d JUMP -> \d\+.*' ..
-        '\d DROP.*',
+  assert_match('ForLoop\_s*' ..
+        'let res: list<number>\_s*' ..
+        '\d NEWLIST size 0\_s*' ..
+        '\d STORE $0\_s*' ..
+        'for i in range(3)\_s*' ..
+        '\d STORE -1 in $1\_s*' ..
+        '\d PUSHNR 3\_s*' ..
+        '\d BCALL range(argc 1)\_s*' ..
+        '\d FOR $1 -> \d\+\_s*' ..
+        '\d STORE $2\_s*' ..
+        'res->add(i)\_s*' ..
+        '\d LOAD $0\_s*' ..
+        '\d LOAD $2\_s*' ..
+        '\d\+ BCALL add(argc 2)\_s*' ..
+        '\d\+ DROP\_s*' ..
+        'endfor\_s*' ..
+        '\d\+ JUMP -> \d\+\_s*' ..
+        '\d\+ DROP',
         instr)
 enddef
 
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    758,
+/**/
     757,
 /**/
     756,