Mercurial > vim
view src/testdir/test_vim9_disassemble.vim @ 19338:ef432264b88a v8.2.0227
patch 8.2.0227: compiling a few instructions not tested
Commit: https://github.com/vim/vim/commit/c2a4b35b86fa8b28a34a9aea8ad16c87dbc6d834
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Feb 6 22:41:16 2020 +0100
patch 8.2.0227: compiling a few instructions not tested
Problem: Compiling a few instructions not tested.
Solution: Add more test cases.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 06 Feb 2020 22:45:04 +0100 |
parents | 1cd6eab65ce0 |
children | 8ff84bc1c89b |
line wrap: on
line source
" Test the :disassemble command, and compilation as a side effect func NotCompiled() echo "not" endfunc let s:scriptvar = 4 let g:globalvar = 'g' def s:ScriptFuncLoad(arg: string) let local = 1 buffers echo arg echo local echo v:version echo s:scriptvar echo g:globalvar echo &tabstop echo $ENVVAR echo @z enddef def Test_disassembleLoad() assert_fails('disass NoFunc', 'E1061:') assert_fails('disass NotCompiled', 'E1062:') let res = execute('disass s:ScriptFuncLoad') assert_match('<SNR>\d*_ScriptFuncLoad.*' \ .. 'buffers.*' \ .. ' EXEC \+buffers.*' \ .. ' LOAD arg\[-1\].*' \ .. ' LOAD $0.*' \ .. ' LOADV v:version.*' \ .. ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*' \ .. ' LOADG g:globalvar.*' \ .. ' LOADENV $ENVVAR.*' \ .. ' LOADREG @z.*' \, res) enddef def s:ScriptFuncPush() let localbool = true let localspec = v:none let localblob = 0z1234 if has('float') let localfloat = 1.234 endif enddef def Test_disassemblePush() let res = execute('disass s:ScriptFuncPush') assert_match('<SNR>\d*_ScriptFuncPush.*' \ .. 'localbool = true.*' \ .. ' PUSH v:true.*' \ .. 'localspec = v:none.*' \ .. ' PUSH v:none.*' \ .. 'localblob = 0z1234.*' \ .. ' PUSHBLOB 0z1234.*' \, res) if has('float') assert_match('<SNR>\d*_ScriptFuncPush.*' \ .. 'localfloat = 1.234.*' \ .. ' PUSHF 1.234.*' \, res) endif enddef def s:ScriptFuncStore() let localnr = 1 localnr = 2 let localstr = 'abc' localstr = 'xyz' v:char = 'abc' s:scriptvar = 'sv' g:globalvar = 'gv' &tabstop = 8 $ENVVAR = 'ev' @z = 'rv' enddef def Test_disassembleStore() let res = execute('disass s:ScriptFuncStore') assert_match('<SNR>\d*_ScriptFuncStore.*' \ .. 'localnr = 2.*' \ .. ' STORE 2 in $0.*' \ .. 'localstr = ''xyz''.*' \ .. ' STORE $1.*' \ .. 'v:char = ''abc''.*' \ .. 'STOREV v:char.*' \ .. 's:scriptvar = ''sv''.*' \ .. ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' \ .. 'g:globalvar = ''gv''.*' \ .. ' STOREG g:globalvar.*' \ .. '&tabstop = 8.*' \ .. ' STOREOPT &tabstop.*' \ .. '$ENVVAR = ''ev''.*' \ .. ' STOREENV $ENVVAR.*' \ .. '@z = ''rv''.*' \ .. ' STOREREG @z.*' \, res) enddef def s:ScriptFuncTry() try echo 'yes' catch /fail/ echo 'no' finally throw 'end' endtry enddef def Test_disassembleTry() 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.*' \, res) enddef def s:ScriptFuncNew() let ll = [1, "two", 333] let dd = #{one: 1, two: "val"} enddef def Test_disassembleNew() 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.*' \, res) enddef def FuncWithArg(arg) echo arg enddef func UserFunc() echo 'nothing' endfunc func UserFuncWithArg(arg) echo a:arg endfunc def s:ScriptFuncCall(): string changenr() char2nr("abc") Test_disassembleNew() FuncWithArg(343) ScriptFuncNew() s:ScriptFuncNew() UserFunc() UserFuncWithArg("foo") let FuncRef = function("UserFunc") FuncRef() let FuncRefWithArg = function("UserFuncWithArg") FuncRefWithArg("bar") return "yes" enddef def Test_disassembleCall() 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_disassembleNew().*' \ .. ' DCALL Test_disassembleNew(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.*' \, res) enddef def HasEval() if has("eval") echo "yes" else echo "no" endif enddef def HasNothing() if has("nothing") echo "yes" else echo "no" endif enddef def HasSomething() if has("nothing") echo "nothing" elseif has("something") echo "something" elseif has("eval") echo "eval" elseif has("less") echo "less" endif enddef def Test_compile_const_expr() assert_equal("\nyes", execute('call HasEval()')) let instr = execute('disassemble HasEval') assert_match('HasEval.*' \ .. 'if has("eval").*' \ .. ' PUSHS "yes".*' \, instr) assert_notmatch('JUMP', instr) assert_equal("\nno", execute('call HasNothing()')) instr = execute('disassemble HasNothing') assert_match('HasNothing.*' \ .. 'if has("nothing").*' \ .. 'else.*' \ .. ' PUSHS "no".*' \, instr) assert_notmatch('PUSHS "yes"', instr) assert_notmatch('JUMP', instr) 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").*' \, instr) assert_notmatch('PUSHS "nothing"', instr) assert_notmatch('PUSHS "something"', instr) assert_notmatch('PUSHS "less"', instr) assert_notmatch('JUMP', instr) enddef def WithLambda(): string let F = {a -> "X" .. a .. "X"} return F("x") enddef def Test_compile_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].*' \, instr) enddef def AndOr(arg): string if arg == 1 && arg != 2 || arg == 4 return 'yes' endif return 'no' enddef def Test_compile_and_or() assert_equal("yes", AndOr(1)) 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\+.*' \, instr) enddef def ForLoop(): list<number> let res: list<number> for i in range(3) res->add(i) endfor return res enddef def Test_compile_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.*' \, instr) enddef let g:number = 42 def Computing() let nr = 3 let nrres = nr + 7 nrres = nr - 7 nrres = nr * 7 nrres = nr / 7 nrres = nr % 7 let anyres = g:number + 7 anyres = g:number - 7 anyres = g:number * 7 anyres = g:number / 7 anyres = g:number % 7 if has('float') let fl = 3.0 let flres = fl + 7.0 flres = fl - 7.0 flres = fl * 7.0 flres = fl / 7.0 endif enddef def Test_computing() let instr = execute('disassemble Computing') assert_match('Computing.*' \ .. 'let nr = 3.*' \ .. '\d STORE 3 in $0.*' \ .. 'let nrres = nr + 7.*' \ .. '\d LOAD $0.*' \ .. '\d PUSHNR 7.*' \ .. '\d OPNR +.*' \ .. '\d STORE $1.*' \ .. 'nrres = nr - 7.*' \ .. '\d OPNR -.*' \ .. 'nrres = nr \* 7.*' \ .. '\d OPNR \*.*' \ .. 'nrres = nr / 7.*' \ .. '\d OPNR /.*' \ .. 'nrres = nr % 7.*' \ .. '\d OPNR %.*' \ .. 'let anyres = g:number + 7.*' \ .. '\d LOADG g:number.*' \ .. '\d PUSHNR 7.*' \ .. '\d OPANY +.*' \ .. '\d STORE $2.*' \ .. 'anyres = g:number - 7.*' \ .. '\d OPANY -.*' \ .. 'anyres = g:number \* 7.*' \ .. '\d OPANY \*.*' \ .. 'anyres = g:number / 7.*' \ .. '\d OPANY /.*' \ .. 'anyres = g:number % 7.*' \ .. '\d OPANY %.*' \, instr) if has('float') assert_match('Computing.*' \ .. 'let fl = 3.0.*' \ .. '\d PUSHF 3.0.*' \ .. '\d STORE $3.*' \ .. 'let flres = fl + 7.0.*' \ .. '\d LOAD $3.*' \ .. '\d PUSHF 7.0.*' \ .. '\d OPFLOAT +.*' \ .. '\d STORE $4.*' \ .. 'flres = fl - 7.0.*' \ .. '\d OPFLOAT -.*' \ .. 'flres = fl \* 7.0.*' \ .. '\d OPFLOAT \*.*' \ .. 'flres = fl / 7.0.*' \ .. '\d OPFLOAT /.*' \, instr) endif enddef " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker