blob: 557b90bcc57ba0b1828b784c6cbbb2e61a250958 [file] [log] [blame]
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001" Test the :disassemble command, and compilation as a side effect
2
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +01003source check.vim
4
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01005func NotCompiled()
6 echo "not"
7endfunc
8
9let s:scriptvar = 4
10let g:globalvar = 'g'
Bram Moolenaard3aac292020-04-19 14:32:17 +020011let b:buffervar = 'b'
12let w:windowvar = 'w'
13let t:tabpagevar = 't'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010014
15def s:ScriptFuncLoad(arg: string)
16 let local = 1
17 buffers
18 echo arg
19 echo local
Bram Moolenaar8a1c1012020-05-07 14:07:25 +020020 echo &lines
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010021 echo v:version
22 echo s:scriptvar
23 echo g:globalvar
Bram Moolenaard3aac292020-04-19 14:32:17 +020024 echo b:buffervar
25 echo w:windowvar
26 echo t:tabpagevar
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010027 echo &tabstop
28 echo $ENVVAR
29 echo @z
30enddef
31
Bram Moolenaarf2460a32020-02-07 22:09:54 +010032def Test_disassemble_load()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010033 assert_fails('disass NoFunc', 'E1061:')
34 assert_fails('disass NotCompiled', 'E1062:')
Bram Moolenaar21456cd2020-02-13 21:29:32 +010035 assert_fails('disass', 'E471:')
36 assert_fails('disass [', 'E475:')
37 assert_fails('disass 234', 'E475:')
38 assert_fails('disass <XX>foo', 'E475:')
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010039
40 let res = execute('disass s:ScriptFuncLoad')
Bram Moolenaar675f7162020-04-12 22:53:54 +020041 assert_match('<SNR>\d*_ScriptFuncLoad.*' ..
42 'buffers.*' ..
43 ' EXEC \+buffers.*' ..
44 ' LOAD arg\[-1\].*' ..
45 ' LOAD $0.*' ..
Bram Moolenaar8a1c1012020-05-07 14:07:25 +020046 ' LOADOPT &lines.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +020047 ' LOADV v:version.*' ..
48 ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*' ..
49 ' LOADG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +020050 ' LOADB b:buffervar.*' ..
51 ' LOADW w:windowvar.*' ..
52 ' LOADT t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +020053 ' LOADENV $ENVVAR.*' ..
54 ' LOADREG @z.*',
55 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010056enddef
57
Bram Moolenaarcfe435d2020-04-25 20:02:55 +020058def s:EditExpand()
59 let filename = "file"
60 let filenr = 123
61 edit the`=filename``=filenr`.txt
62enddef
63
64def Test_disassemble_exec_expr()
65 let res = execute('disass s:EditExpand')
66 assert_match('<SNR>\d*_EditExpand.*' ..
67 ' let filename = "file".*' ..
68 '\d PUSHS "file".*' ..
69 '\d STORE $0.*' ..
70 ' let filenr = 123.*' ..
71 '\d STORE 123 in $1.*' ..
72 ' edit the`=filename``=filenr`.txt.*' ..
73 '\d PUSHS "edit the".*' ..
74 '\d LOAD $0.*' ..
75 '\d LOAD $1.*' ..
76 '\d 2STRING stack\[-1\].*' ..
77 '\d PUSHS ".txt".*' ..
78 '\d EXECCONCAT 4.*' ..
79 '\d PUSHNR 0.*' ..
80 '\d RETURN',
81 res)
82enddef
83
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010084def s:ScriptFuncPush()
85 let localbool = true
86 let localspec = v:none
87 let localblob = 0z1234
88 if has('float')
89 let localfloat = 1.234
90 endif
91enddef
92
Bram Moolenaarf2460a32020-02-07 22:09:54 +010093def Test_disassemble_push()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010094 let res = execute('disass s:ScriptFuncPush')
Bram Moolenaar675f7162020-04-12 22:53:54 +020095 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
96 'localbool = true.*' ..
97 ' PUSH v:true.*' ..
98 'localspec = v:none.*' ..
99 ' PUSH v:none.*' ..
100 'localblob = 0z1234.*' ..
101 ' PUSHBLOB 0z1234.*',
102 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100103 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200104 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
105 'localfloat = 1.234.*' ..
106 ' PUSHF 1.234.*',
107 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100108 endif
109enddef
110
111def s:ScriptFuncStore()
112 let localnr = 1
113 localnr = 2
114 let localstr = 'abc'
115 localstr = 'xyz'
116 v:char = 'abc'
117 s:scriptvar = 'sv'
118 g:globalvar = 'gv'
Bram Moolenaard3aac292020-04-19 14:32:17 +0200119 b:buffervar = 'bv'
120 w:windowvar = 'wv'
121 t:tabpagevar = 'tv'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100122 &tabstop = 8
123 $ENVVAR = 'ev'
124 @z = 'rv'
125enddef
126
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100127def Test_disassemble_store()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100128 let res = execute('disass s:ScriptFuncStore')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200129 assert_match('<SNR>\d*_ScriptFuncStore.*' ..
130 'let localnr = 1.*' ..
131 'localnr = 2.*' ..
132 ' STORE 2 in $0.*' ..
133 'let localstr = ''abc''.*' ..
134 'localstr = ''xyz''.*' ..
135 ' STORE $1.*' ..
136 'v:char = ''abc''.*' ..
137 'STOREV v:char.*' ..
138 's:scriptvar = ''sv''.*' ..
139 ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
140 'g:globalvar = ''gv''.*' ..
141 ' STOREG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +0200142 'b:buffervar = ''bv''.*' ..
143 ' STOREB b:buffervar.*' ..
144 'w:windowvar = ''wv''.*' ..
145 ' STOREW w:windowvar.*' ..
146 't:tabpagevar = ''tv''.*' ..
147 ' STORET t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200148 '&tabstop = 8.*' ..
149 ' STOREOPT &tabstop.*' ..
150 '$ENVVAR = ''ev''.*' ..
151 ' STOREENV $ENVVAR.*' ..
152 '@z = ''rv''.*' ..
153 ' STOREREG @z.*',
154 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100155enddef
156
Bram Moolenaarcb790402020-05-15 20:53:00 +0200157def s:ScriptFuncStoreMember()
158 let locallist: list<number> = []
159 locallist[0] = 123
160 let localdict: dict<number> = {}
161 localdict["a"] = 456
162enddef
163
164def Test_disassemble_store_member()
165 let res = execute('disass s:ScriptFuncStoreMember')
166 assert_match('<SNR>\d*_ScriptFuncStoreMember\_s*' ..
167 'let locallist: list<number> = []\_s*' ..
168 '\d NEWLIST size 0\_s*' ..
169 '\d STORE $0\_s*' ..
170 'locallist\[0\] = 123\_s*' ..
171 '\d PUSHNR 123\_s*' ..
172 '\d PUSHNR 0\_s*' ..
173 '\d LOAD $0\_s*' ..
174 '\d STORELIST\_s*' ..
175 'let localdict: dict<number> = {}\_s*' ..
176 '\d NEWDICT size 0\_s*' ..
177 '\d STORE $1\_s*' ..
178 'localdict\["a"\] = 456\_s*' ..
179 '\d\+ PUSHNR 456\_s*' ..
180 '\d\+ PUSHS "a"\_s*' ..
181 '\d\+ LOAD $1\_s*' ..
182 '\d\+ STOREDICT\_s*' ..
183 '\d\+ PUSHNR 0\_s*' ..
184 '\d\+ RETURN',
185 res)
186enddef
187
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200188def s:ListAssign()
189 let x: string
190 let y: string
191 let l: list<any>
192 [x, y; l] = g:stringlist
193enddef
194
195def Test_disassemble_list_assign()
196 let res = execute('disass s:ListAssign')
197 assert_match('<SNR>\d*_ListAssign\_s*' ..
198 'let x: string\_s*' ..
199 '\d PUSHS "\[NULL\]"\_s*' ..
200 '\d STORE $0\_s*' ..
201 'let y: string\_s*' ..
202 '\d PUSHS "\[NULL\]"\_s*' ..
203 '\d STORE $1\_s*' ..
204 'let l: list<any>\_s*' ..
205 '\d NEWLIST size 0\_s*' ..
206 '\d STORE $2\_s*' ..
207 '\[x, y; l\] = g:stringlist\_s*' ..
208 '\d LOADG g:stringlist\_s*' ..
209 '\d CHECKTYPE list stack\[-1\]\_s*' ..
210 '\d CHECKLEN >= 2\_s*' ..
211 '\d\+ ITEM 0\_s*' ..
212 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
213 '\d\+ STORE $0\_s*' ..
214 '\d\+ ITEM 1\_s*' ..
215 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
216 '\d\+ STORE $1\_s*' ..
217 '\d\+ SLICE 2\_s*' ..
218 '\d\+ STORE $2\_s*' ..
219 '\d\+ PUSHNR 0\_s*' ..
220 '\d\+ RETURN',
221 res)
222enddef
223
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200224def s:ScriptFuncUnlet()
225 g:somevar = "value"
226 unlet g:somevar
227 unlet! g:somevar
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200228 unlet $SOMEVAR
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200229enddef
230
231def Test_disassemble_unlet()
232 let res = execute('disass s:ScriptFuncUnlet')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200233 assert_match('<SNR>\d*_ScriptFuncUnlet\_s*' ..
234 'g:somevar = "value"\_s*' ..
235 '\d PUSHS "value"\_s*' ..
236 '\d STOREG g:somevar\_s*' ..
237 'unlet g:somevar\_s*' ..
238 '\d UNLET g:somevar\_s*' ..
239 'unlet! g:somevar\_s*' ..
240 '\d UNLET! g:somevar\_s*' ..
241 'unlet $SOMEVAR\_s*' ..
242 '\d UNLETENV $SOMEVAR\_s*',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200243 res)
244enddef
245
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100246def s:ScriptFuncTry()
247 try
Bram Moolenaarcb790402020-05-15 20:53:00 +0200248 echo "yes"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100249 catch /fail/
Bram Moolenaarcb790402020-05-15 20:53:00 +0200250 echo "no"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100251 finally
Bram Moolenaarcb790402020-05-15 20:53:00 +0200252 throw "end"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100253 endtry
254enddef
255
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100256def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100257 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200258 assert_match('<SNR>\d*_ScriptFuncTry\_s*' ..
259 'try\_s*' ..
260 '\d TRY catch -> \d\+, finally -> \d\+\_s*' ..
261 'echo "yes"\_s*' ..
262 '\d PUSHS "yes"\_s*' ..
263 '\d ECHO 1\_s*' ..
264 'catch /fail/\_s*' ..
265 '\d JUMP -> \d\+\_s*' ..
266 '\d PUSH v:exception\_s*' ..
267 '\d PUSHS "fail"\_s*' ..
268 '\d COMPARESTRING =\~\_s*' ..
269 '\d JUMP_IF_FALSE -> \d\+\_s*' ..
270 '\d CATCH\_s*' ..
271 'echo "no"\_s*' ..
272 '\d\+ PUSHS "no"\_s*' ..
273 '\d\+ ECHO 1\_s*' ..
274 'finally\_s*' ..
275 'throw "end"\_s*' ..
276 '\d\+ PUSHS "end"\_s*' ..
277 '\d\+ THROW\_s*' ..
278 'endtry\_s*' ..
279 '\d\+ ENDTRY',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200280 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100281enddef
282
283def s:ScriptFuncNew()
284 let ll = [1, "two", 333]
285 let dd = #{one: 1, two: "val"}
286enddef
287
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100288def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100289 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200290 assert_match('<SNR>\d*_ScriptFuncNew\_s*' ..
291 'let ll = \[1, "two", 333\]\_s*' ..
292 '\d PUSHNR 1\_s*' ..
293 '\d PUSHS "two"\_s*' ..
294 '\d PUSHNR 333\_s*' ..
295 '\d NEWLIST size 3\_s*' ..
296 '\d STORE $0\_s*' ..
297 'let dd = #{one: 1, two: "val"}\_s*' ..
298 '\d PUSHS "one"\_s*' ..
299 '\d PUSHNR 1\_s*' ..
300 '\d PUSHS "two"\_s*' ..
301 '\d PUSHS "val"\_s*' ..
302 '\d NEWDICT size 2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200303 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100304enddef
305
Bram Moolenaar6e949782020-04-13 17:21:00 +0200306def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100307 echo arg
308enddef
309
310func UserFunc()
311 echo 'nothing'
312endfunc
313
314func UserFuncWithArg(arg)
315 echo a:arg
316endfunc
317
318def s:ScriptFuncCall(): string
319 changenr()
320 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100321 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100322 FuncWithArg(343)
323 ScriptFuncNew()
324 s:ScriptFuncNew()
325 UserFunc()
326 UserFuncWithArg("foo")
327 let FuncRef = function("UserFunc")
328 FuncRef()
329 let FuncRefWithArg = function("UserFuncWithArg")
330 FuncRefWithArg("bar")
331 return "yes"
332enddef
333
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100334def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100335 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200336 assert_match('<SNR>\d\+_ScriptFuncCall\_s*' ..
337 'changenr()\_s*' ..
338 '\d BCALL changenr(argc 0)\_s*' ..
339 '\d DROP\_s*' ..
340 'char2nr("abc")\_s*' ..
341 '\d PUSHS "abc"\_s*' ..
342 '\d BCALL char2nr(argc 1)\_s*' ..
343 '\d DROP\_s*' ..
344 'Test_disassemble_new()\_s*' ..
345 '\d DCALL Test_disassemble_new(argc 0)\_s*' ..
346 '\d DROP\_s*' ..
347 'FuncWithArg(343)\_s*' ..
348 '\d\+ PUSHNR 343\_s*' ..
349 '\d\+ DCALL FuncWithArg(argc 1)\_s*' ..
350 '\d\+ DROP\_s*' ..
351 'ScriptFuncNew()\_s*' ..
352 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
353 '\d\+ DROP\_s*' ..
354 's:ScriptFuncNew()\_s*' ..
355 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
356 '\d\+ DROP\_s*' ..
357 'UserFunc()\_s*' ..
358 '\d\+ UCALL UserFunc(argc 0)\_s*' ..
359 '\d\+ DROP\_s*' ..
360 'UserFuncWithArg("foo")\_s*' ..
361 '\d\+ PUSHS "foo"\_s*' ..
362 '\d\+ UCALL UserFuncWithArg(argc 1)\_s*' ..
363 '\d\+ DROP\_s*' ..
364 'let FuncRef = function("UserFunc")\_s*' ..
365 '\d\+ PUSHS "UserFunc"\_s*' ..
366 '\d\+ BCALL function(argc 1)\_s*' ..
367 '\d\+ STORE $0\_s*' ..
368 'FuncRef()\_s*' ..
369 '\d\+ LOAD $\d\_s*' ..
370 '\d\+ PCALL (argc 0)\_s*' ..
371 '\d\+ DROP\_s*' ..
372 'let FuncRefWithArg = function("UserFuncWithArg")\_s*' ..
373 '\d\+ PUSHS "UserFuncWithArg"\_s*' ..
374 '\d\+ BCALL function(argc 1)\_s*' ..
375 '\d\+ STORE $1\_s*' ..
376 'FuncRefWithArg("bar")\_s*' ..
377 '\d\+ PUSHS "bar"\_s*' ..
378 '\d\+ LOAD $\d\_s*' ..
379 '\d\+ PCALL (argc 1)\_s*' ..
380 '\d\+ DROP\_s*' ..
381 'return "yes"\_s*' ..
382 '\d\+ PUSHS "yes"\_s*' ..
383 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200384 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100385enddef
386
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200387def s:CreateRefs()
388 let local = 'a'
389 def Append(arg: string)
390 local ..= arg
391 enddef
392 g:Append = Append
393 def Get(): string
394 return local
395 enddef
396 g:Get = Get
397enddef
398
399def Test_disassemble_closure()
400 CreateRefs()
401 let res = execute('disass g:Append')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200402 assert_match('<lambda>\d\_s*' ..
403 'local ..= arg\_s*' ..
404 '\d LOADOUTER $0\_s*' ..
405 '\d LOAD arg\[-1\]\_s*' ..
406 '\d CONCAT\_s*' ..
407 '\d STOREOUTER $0\_s*' ..
408 '\d PUSHNR 0\_s*' ..
409 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200410 res)
411
412 res = execute('disass g:Get')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200413 assert_match('<lambda>\d\_s*' ..
414 'return local\_s*' ..
415 '\d LOADOUTER $0\_s*' ..
416 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200417 res)
418
419 unlet g:Append
420 unlet g:Get
421enddef
422
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100423
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200424def EchoArg(arg: string): string
425 return arg
426enddef
427def RefThis(): func
428 return function('EchoArg')
429enddef
430def s:ScriptPCall()
431 RefThis()("text")
432enddef
433
434def Test_disassemble_pcall()
435 let res = execute('disass s:ScriptPCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200436 assert_match('<SNR>\d\+_ScriptPCall\_s*' ..
437 'RefThis()("text")\_s*' ..
438 '\d DCALL RefThis(argc 0)\_s*' ..
439 '\d PUSHS "text"\_s*' ..
440 '\d PCALL top (argc 1)\_s*' ..
441 '\d PCALL end\_s*' ..
442 '\d DROP\_s*' ..
443 '\d PUSHNR 0\_s*' ..
444 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200445 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200446enddef
447
448
Bram Moolenaara26b9702020-04-18 19:53:28 +0200449def s:FuncWithForwardCall(): string
450 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100451enddef
452
453def DefinedLater(arg: string): string
454 return arg
455enddef
456
457def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200458 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200459 assert_match('FuncWithForwardCall\_s*' ..
460 'return g:DefinedLater("yes")\_s*' ..
461 '\d PUSHS "yes"\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200462 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200463 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200464 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100465
466 " Calling the function will change UCALL into the faster DCALL
467 assert_equal('yes', FuncWithForwardCall())
468
Bram Moolenaara26b9702020-04-18 19:53:28 +0200469 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200470 assert_match('FuncWithForwardCall\_s*' ..
471 'return g:DefinedLater("yes")\_s*' ..
472 '\d PUSHS "yes"\_s*' ..
473 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200474 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200475 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100476enddef
477
478
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100479def FuncWithDefault(arg: string = 'default'): string
480 return arg
481enddef
482
483def Test_disassemble_call_default()
484 let res = execute('disass FuncWithDefault')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200485 assert_match('FuncWithDefault\_s*' ..
486 '\d PUSHS "default"\_s*' ..
487 '\d STORE arg\[-1]\_s*' ..
488 'return arg\_s*' ..
489 '\d LOAD arg\[-1]\_s*' ..
490 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200491 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100492enddef
493
494
Bram Moolenaar158906c2020-02-06 20:39:45 +0100495def HasEval()
496 if has("eval")
497 echo "yes"
498 else
499 echo "no"
500 endif
501enddef
502
503def HasNothing()
504 if has("nothing")
505 echo "yes"
506 else
507 echo "no"
508 endif
509enddef
510
511def HasSomething()
512 if has("nothing")
513 echo "nothing"
514 elseif has("something")
515 echo "something"
516 elseif has("eval")
517 echo "eval"
518 elseif has("less")
519 echo "less"
520 endif
521enddef
522
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100523def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100524 assert_equal("\nyes", execute('call HasEval()'))
525 let instr = execute('disassemble HasEval')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200526 assert_match('HasEval\_s*' ..
527 'if has("eval")\_s*' ..
528 'echo "yes"\_s*' ..
529 '\d PUSHS "yes"\_s*' ..
530 '\d ECHO 1\_s*' ..
531 'else\_s*' ..
532 'echo "no"\_s*' ..
533 'endif\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200534 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100535 assert_notmatch('JUMP', instr)
536
537 assert_equal("\nno", execute('call HasNothing()'))
538 instr = execute('disassemble HasNothing')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200539 assert_match('HasNothing\_s*' ..
540 'if has("nothing")\_s*' ..
541 'echo "yes"\_s*' ..
542 'else\_s*' ..
543 'echo "no"\_s*' ..
544 '\d PUSHS "no"\_s*' ..
545 '\d ECHO 1\_s*' ..
546 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200547 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100548 assert_notmatch('PUSHS "yes"', instr)
549 assert_notmatch('JUMP', instr)
550
551 assert_equal("\neval", execute('call HasSomething()'))
552 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200553 assert_match('HasSomething.*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200554 'if has("nothing")\_s*' ..
555 'echo "nothing"\_s*' ..
556 'elseif has("something")\_s*' ..
557 'echo "something"\_s*' ..
558 'elseif has("eval")\_s*' ..
559 'echo "eval"\_s*' ..
560 '\d PUSHS "eval"\_s*' ..
561 '\d ECHO 1\_s*' ..
562 'elseif has("less").*' ..
563 'echo "less"\_s*' ..
564 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200565 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100566 assert_notmatch('PUSHS "nothing"', instr)
567 assert_notmatch('PUSHS "something"', instr)
568 assert_notmatch('PUSHS "less"', instr)
569 assert_notmatch('JUMP', instr)
570enddef
571
Bram Moolenaarefd88552020-06-18 20:50:10 +0200572def ReturnInIf(): string
573 if g:cond
574 return "yes"
575 else
576 return "no"
577 endif
578enddef
579
580def Test_disassemble_return_in_if()
581 let instr = execute('disassemble ReturnInIf')
582 assert_match('ReturnInIf\_s*' ..
583 'if g:cond\_s*' ..
584 '0 LOADG g:cond\_s*' ..
585 '1 JUMP_IF_FALSE -> 4\_s*' ..
586 'return "yes"\_s*' ..
587 '2 PUSHS "yes"\_s*' ..
588 '3 RETURN\_s*' ..
589 'else\_s*' ..
590 ' return "no"\_s*' ..
591 '4 PUSHS "no"\_s*' ..
592 '5 RETURN$',
593 instr)
594enddef
595
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100596def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200597 let Funky1: func
598 let Funky2: func = function("len")
599 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100600enddef
601
602def Test_disassemble_function()
603 let instr = execute('disassemble WithFunc')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200604 assert_match('WithFunc\_s*' ..
605 'let Funky1: func\_s*' ..
606 '0 PUSHFUNC "\[none]"\_s*' ..
607 '1 STORE $0\_s*' ..
608 'let Funky2: func = function("len")\_s*' ..
609 '2 PUSHS "len"\_s*' ..
610 '3 BCALL function(argc 1)\_s*' ..
611 '4 STORE $1\_s*' ..
612 'let Party2: func = funcref("UserFunc")\_s*' ..
613 '\d PUSHS "UserFunc"\_s*' ..
614 '\d BCALL funcref(argc 1)\_s*' ..
615 '\d STORE $2\_s*' ..
616 '\d PUSHNR 0\_s*' ..
617 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200618 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100619enddef
620
621if has('channel')
622 def WithChannel()
623 let job1: job
624 let job2: job = job_start("donothing")
625 let chan1: channel
626 enddef
627endif
628
629def Test_disassemble_channel()
630 CheckFeature channel
631
632 let instr = execute('disassemble WithChannel')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200633 assert_match('WithChannel\_s*' ..
634 'let job1: job\_s*' ..
635 '\d PUSHJOB "no process"\_s*' ..
636 '\d STORE $0\_s*' ..
637 'let job2: job = job_start("donothing")\_s*' ..
638 '\d PUSHS "donothing"\_s*' ..
639 '\d BCALL job_start(argc 1)\_s*' ..
640 '\d STORE $1\_s*' ..
641 'let chan1: channel\_s*' ..
642 '\d PUSHCHANNEL 0\_s*' ..
643 '\d STORE $2\_s*' ..
644 '\d PUSHNR 0\_s*' ..
645 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200646 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100647enddef
648
Bram Moolenaar777770f2020-02-06 21:27:08 +0100649def WithLambda(): string
650 let F = {a -> "X" .. a .. "X"}
651 return F("x")
652enddef
653
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100654def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100655 assert_equal("XxX", WithLambda())
656 let instr = execute('disassemble WithLambda')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200657 assert_match('WithLambda\_s*' ..
658 'let F = {a -> "X" .. a .. "X"}\_s*' ..
659 '\d FUNCREF <lambda>\d\+ $1\_s*' ..
660 '\d STORE $0\_s*' ..
661 'return F("x")\_s*' ..
662 '\d PUSHS "x"\_s*' ..
663 '\d LOAD $0\_s*' ..
664 '\d PCALL (argc 1)\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200665 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200666 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100667enddef
668
Bram Moolenaar6e949782020-04-13 17:21:00 +0200669def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100670 if arg == 1 && arg != 2 || arg == 4
671 return 'yes'
672 endif
673 return 'no'
674enddef
675
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100676def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100677 assert_equal("yes", AndOr(1))
678 assert_equal("no", AndOr(2))
679 assert_equal("yes", AndOr(4))
680 let instr = execute('disassemble AndOr')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200681 assert_match('AndOr\_s*' ..
682 'if arg == 1 && arg != 2 || arg == 4\_s*' ..
683 '\d LOAD arg\[-1]\_s*' ..
684 '\d PUSHNR 1\_s*' ..
685 '\d COMPAREANY ==\_s*' ..
686 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+\_s*' ..
687 '\d LOAD arg\[-1]\_s*' ..
688 '\d PUSHNR 2\_s*' ..
689 '\d COMPAREANY !=\_s*' ..
690 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+\_s*' ..
691 '\d LOAD arg\[-1]\_s*' ..
692 '\d\+ PUSHNR 4\_s*' ..
693 '\d\+ COMPAREANY ==\_s*' ..
694 '\d\+ JUMP_IF_FALSE -> \d\+',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200695 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100696enddef
697
Bram Moolenaar04d05222020-02-06 22:06:54 +0100698def ForLoop(): list<number>
699 let res: list<number>
700 for i in range(3)
701 res->add(i)
702 endfor
703 return res
704enddef
705
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100706def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100707 assert_equal([0, 1, 2], ForLoop())
708 let instr = execute('disassemble ForLoop')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200709 assert_match('ForLoop\_s*' ..
710 'let res: list<number>\_s*' ..
711 '\d NEWLIST size 0\_s*' ..
712 '\d STORE $0\_s*' ..
713 'for i in range(3)\_s*' ..
714 '\d STORE -1 in $1\_s*' ..
715 '\d PUSHNR 3\_s*' ..
716 '\d BCALL range(argc 1)\_s*' ..
717 '\d FOR $1 -> \d\+\_s*' ..
718 '\d STORE $2\_s*' ..
719 'res->add(i)\_s*' ..
720 '\d LOAD $0\_s*' ..
721 '\d LOAD $2\_s*' ..
722 '\d\+ BCALL add(argc 2)\_s*' ..
723 '\d\+ DROP\_s*' ..
724 'endfor\_s*' ..
725 '\d\+ JUMP -> \d\+\_s*' ..
726 '\d\+ DROP',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200727 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100728enddef
729
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100730let g:number = 42
731
732def Computing()
733 let nr = 3
734 let nrres = nr + 7
735 nrres = nr - 7
736 nrres = nr * 7
737 nrres = nr / 7
738 nrres = nr % 7
739
740 let anyres = g:number + 7
741 anyres = g:number - 7
742 anyres = g:number * 7
743 anyres = g:number / 7
744 anyres = g:number % 7
745
746 if has('float')
747 let fl = 3.0
748 let flres = fl + 7.0
749 flres = fl - 7.0
750 flres = fl * 7.0
751 flres = fl / 7.0
752 endif
753enddef
754
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100755def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100756 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200757 assert_match('Computing.*' ..
758 'let nr = 3.*' ..
759 '\d STORE 3 in $0.*' ..
760 'let nrres = nr + 7.*' ..
761 '\d LOAD $0.*' ..
762 '\d PUSHNR 7.*' ..
763 '\d OPNR +.*' ..
764 '\d STORE $1.*' ..
765 'nrres = nr - 7.*' ..
766 '\d OPNR -.*' ..
767 'nrres = nr \* 7.*' ..
768 '\d OPNR \*.*' ..
769 'nrres = nr / 7.*' ..
770 '\d OPNR /.*' ..
771 'nrres = nr % 7.*' ..
772 '\d OPNR %.*' ..
773 'let anyres = g:number + 7.*' ..
774 '\d LOADG g:number.*' ..
775 '\d PUSHNR 7.*' ..
776 '\d OPANY +.*' ..
777 '\d STORE $2.*' ..
778 'anyres = g:number - 7.*' ..
779 '\d OPANY -.*' ..
780 'anyres = g:number \* 7.*' ..
781 '\d OPANY \*.*' ..
782 'anyres = g:number / 7.*' ..
783 '\d OPANY /.*' ..
784 'anyres = g:number % 7.*' ..
785 '\d OPANY %.*',
786 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100787 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200788 assert_match('Computing.*' ..
789 'let fl = 3.0.*' ..
790 '\d PUSHF 3.0.*' ..
791 '\d STORE $3.*' ..
792 'let flres = fl + 7.0.*' ..
793 '\d LOAD $3.*' ..
794 '\d PUSHF 7.0.*' ..
795 '\d OPFLOAT +.*' ..
796 '\d STORE $4.*' ..
797 'flres = fl - 7.0.*' ..
798 '\d OPFLOAT -.*' ..
799 'flres = fl \* 7.0.*' ..
800 '\d OPFLOAT \*.*' ..
801 'flres = fl / 7.0.*' ..
802 '\d OPFLOAT /.*',
803 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100804 endif
805enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100806
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100807def AddListBlob()
808 let reslist = [1, 2] + [3, 4]
809 let resblob = 0z1122 + 0z3344
810enddef
811
812def Test_disassemble_add_list_blob()
813 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200814 assert_match('AddListBlob.*' ..
815 'let reslist = \[1, 2] + \[3, 4].*' ..
816 '\d PUSHNR 1.*' ..
817 '\d PUSHNR 2.*' ..
818 '\d NEWLIST size 2.*' ..
819 '\d PUSHNR 3.*' ..
820 '\d PUSHNR 4.*' ..
821 '\d NEWLIST size 2.*' ..
822 '\d ADDLIST.*' ..
823 '\d STORE $.*.*' ..
824 'let resblob = 0z1122 + 0z3344.*' ..
825 '\d PUSHBLOB 0z1122.*' ..
826 '\d PUSHBLOB 0z3344.*' ..
827 '\d ADDBLOB.*' ..
828 '\d STORE $.*',
829 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100830enddef
831
832let g:aa = 'aa'
833def ConcatString(): string
834 let res = g:aa .. "bb"
835 return res
836enddef
837
838def Test_disassemble_concat()
839 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200840 assert_match('ConcatString.*' ..
841 'let res = g:aa .. "bb".*' ..
842 '\d LOADG g:aa.*' ..
843 '\d PUSHS "bb".*' ..
844 '\d 2STRING stack\[-2].*' ..
845 '\d CONCAT.*' ..
846 '\d STORE $.*',
847 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100848 assert_equal('aabb', ConcatString())
849enddef
850
851def ListIndex(): number
852 let l = [1, 2, 3]
853 let res = l[1]
854 return res
855enddef
856
857def Test_disassemble_list_index()
858 let instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200859 assert_match('ListIndex\_s*' ..
860 'let l = \[1, 2, 3]\_s*' ..
861 '\d PUSHNR 1\_s*' ..
862 '\d PUSHNR 2\_s*' ..
863 '\d PUSHNR 3\_s*' ..
864 '\d NEWLIST size 3\_s*' ..
865 '\d STORE $0\_s*' ..
866 'let res = l\[1]\_s*' ..
867 '\d LOAD $0\_s*' ..
868 '\d PUSHNR 1\_s*' ..
869 '\d INDEX\_s*' ..
870 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200871 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100872 assert_equal(2, ListIndex())
873enddef
874
875def DictMember(): number
876 let d = #{item: 1}
877 let res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200878 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100879 return res
880enddef
881
882def Test_disassemble_dict_member()
883 let instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200884 assert_match('DictMember\_s*' ..
885 'let d = #{item: 1}\_s*' ..
886 '\d PUSHS "item"\_s*' ..
887 '\d PUSHNR 1\_s*' ..
888 '\d NEWDICT size 1\_s*' ..
889 '\d STORE $0\_s*' ..
890 'let res = d.item\_s*' ..
891 '\d\+ LOAD $0\_s*' ..
892 '\d\+ MEMBER item\_s*' ..
893 '\d\+ STORE $1\_s*' ..
894 'res = d\["item"\]\_s*' ..
895 '\d\+ LOAD $0\_s*' ..
896 '\d\+ PUSHS "item"\_s*' ..
897 '\d\+ MEMBER\_s*' ..
898 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200899 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100900 call assert_equal(1, DictMember())
901enddef
902
903def NegateNumber(): number
904 let nr = 9
905 let plus = +nr
906 let res = -nr
907 return res
908enddef
909
910def Test_disassemble_negate_number()
911 let instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200912 assert_match('NegateNumber\_s*' ..
913 'let nr = 9\_s*' ..
914 '\d STORE 9 in $0\_s*' ..
915 'let plus = +nr\_s*' ..
916 '\d LOAD $0\_s*' ..
917 '\d CHECKNR\_s*' ..
918 '\d STORE $1\_s*' ..
919 'let res = -nr\_s*' ..
920 '\d LOAD $0\_s*' ..
921 '\d NEGATENR\_s*' ..
922 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200923 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100924 call assert_equal(-9, NegateNumber())
925enddef
926
927def InvertBool(): bool
928 let flag = true
929 let invert = !flag
930 let res = !!flag
931 return res
932enddef
933
934def Test_disassemble_invert_bool()
935 let instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200936 assert_match('InvertBool\_s*' ..
937 'let flag = true\_s*' ..
938 '\d PUSH v:true\_s*' ..
939 '\d STORE $0\_s*' ..
940 'let invert = !flag\_s*' ..
941 '\d LOAD $0\_s*' ..
942 '\d INVERT (!val)\_s*' ..
943 '\d STORE $1\_s*' ..
944 'let res = !!flag\_s*' ..
945 '\d LOAD $0\_s*' ..
946 '\d 2BOOL (!!val)\_s*' ..
947 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200948 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100949 call assert_equal(true, InvertBool())
950enddef
951
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100952def Test_disassemble_compare()
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100953 let cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +0200954 ['true == isFalse', 'COMPAREBOOL =='],
955 ['true != isFalse', 'COMPAREBOOL !='],
956 ['v:none == isNull', 'COMPARESPECIAL =='],
957 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200958
Bram Moolenaara5565e42020-05-09 15:44:01 +0200959 ['111 == aNumber', 'COMPARENR =='],
960 ['111 != aNumber', 'COMPARENR !='],
961 ['111 > aNumber', 'COMPARENR >'],
962 ['111 < aNumber', 'COMPARENR <'],
963 ['111 >= aNumber', 'COMPARENR >='],
964 ['111 <= aNumber', 'COMPARENR <='],
965 ['111 =~ aNumber', 'COMPARENR =\~'],
966 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200967
Bram Moolenaara5565e42020-05-09 15:44:01 +0200968 ['"xx" != aString', 'COMPARESTRING !='],
969 ['"xx" > aString', 'COMPARESTRING >'],
970 ['"xx" < aString', 'COMPARESTRING <'],
971 ['"xx" >= aString', 'COMPARESTRING >='],
972 ['"xx" <= aString', 'COMPARESTRING <='],
973 ['"xx" =~ aString', 'COMPARESTRING =\~'],
974 ['"xx" !~ aString', 'COMPARESTRING !\~'],
975 ['"xx" is aString', 'COMPARESTRING is'],
976 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200977
Bram Moolenaara5565e42020-05-09 15:44:01 +0200978 ['0z11 == aBlob', 'COMPAREBLOB =='],
979 ['0z11 != aBlob', 'COMPAREBLOB !='],
980 ['0z11 is aBlob', 'COMPAREBLOB is'],
981 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200982
Bram Moolenaara5565e42020-05-09 15:44:01 +0200983 ['[1, 2] == aList', 'COMPARELIST =='],
984 ['[1, 2] != aList', 'COMPARELIST !='],
985 ['[1, 2] is aList', 'COMPARELIST is'],
986 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200987
Bram Moolenaara5565e42020-05-09 15:44:01 +0200988 ['#{a: 1} == aDict', 'COMPAREDICT =='],
989 ['#{a: 1} != aDict', 'COMPAREDICT !='],
990 ['#{a: 1} is aDict', 'COMPAREDICT is'],
991 ['#{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200992
993 ['{->33} == {->44}', 'COMPAREFUNC =='],
994 ['{->33} != {->44}', 'COMPAREFUNC !='],
995 ['{->33} is {->44}', 'COMPAREFUNC is'],
996 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
997
998 ['77 == g:xx', 'COMPAREANY =='],
999 ['77 != g:xx', 'COMPAREANY !='],
1000 ['77 > g:xx', 'COMPAREANY >'],
1001 ['77 < g:xx', 'COMPAREANY <'],
1002 ['77 >= g:xx', 'COMPAREANY >='],
1003 ['77 <= g:xx', 'COMPAREANY <='],
1004 ['77 =~ g:xx', 'COMPAREANY =\~'],
1005 ['77 !~ g:xx', 'COMPAREANY !\~'],
1006 ['77 is g:xx', 'COMPAREANY is'],
1007 ['77 isnot g:xx', 'COMPAREANY isnot'],
1008 ]
Bram Moolenaara5565e42020-05-09 15:44:01 +02001009 let floatDecl = ''
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001010 if has('float')
1011 cases->extend([
Bram Moolenaara5565e42020-05-09 15:44:01 +02001012 ['1.1 == aFloat', 'COMPAREFLOAT =='],
1013 ['1.1 != aFloat', 'COMPAREFLOAT !='],
1014 ['1.1 > aFloat', 'COMPAREFLOAT >'],
1015 ['1.1 < aFloat', 'COMPAREFLOAT <'],
1016 ['1.1 >= aFloat', 'COMPAREFLOAT >='],
1017 ['1.1 <= aFloat', 'COMPAREFLOAT <='],
1018 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
1019 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001020 ])
Bram Moolenaara5565e42020-05-09 15:44:01 +02001021 floatDecl = 'let aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001022 endif
1023
1024 let nr = 1
1025 for case in cases
Bram Moolenaara5565e42020-05-09 15:44:01 +02001026 " declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001027 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaara5565e42020-05-09 15:44:01 +02001028 ' let isFalse = false',
1029 ' let isNull = v:null',
1030 ' let aNumber = 222',
1031 ' let aString = "yy"',
1032 ' let aBlob = 0z22',
1033 ' let aList = [3, 4]',
1034 ' let aDict = #{x: 2}',
1035 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +02001036 ' if ' .. case[0],
1037 ' echo 42'
1038 ' endif',
1039 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001040 source Xdisassemble
1041 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +02001042 assert_match('TestCase' .. nr .. '.*' ..
1043 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1044 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +02001045 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001046 '\d ' .. case[1] .. '.*' ..
1047 '\d JUMP_IF_FALSE -> \d\+.*',
1048 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001049
1050 nr += 1
1051 endfor
1052
Bram Moolenaar22da5592020-03-19 14:52:20 +01001053 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001054enddef
1055
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001056def Test_disassemble_compare_const()
1057 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +02001058 ['"xx" == "yy"', false],
1059 ['"aa" == "aa"', true],
1060 ['has("eval") ? true : false', true],
1061 ['has("asdf") ? true : false', false],
1062 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001063
1064 let nr = 1
1065 for case in cases
1066 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001067 ' if ' .. case[0],
1068 ' echo 42'
1069 ' endif',
1070 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001071 source Xdisassemble
1072 let instr = execute('disassemble TestCase' .. nr)
1073 if case[1]
1074 " condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02001075 assert_match('TestCase' .. nr .. '.*' ..
1076 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1077 '\d PUSHNR 42.*' ..
1078 '\d ECHO 1.*' ..
1079 '\d PUSHNR 0.*' ..
1080 '\d RETURN.*',
1081 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001082 else
1083 " condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02001084 assert_match('TestCase' .. nr .. '.*' ..
1085 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
1086 'echo 42[ \n]*' ..
1087 'endif[ \n]*' ..
1088 '\s*\d PUSHNR 0.*' ..
1089 '\d RETURN.*',
1090 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001091 endif
1092
1093 nr += 1
1094 endfor
1095
1096 delete('Xdisassemble')
1097enddef
1098
Bram Moolenaarad39c092020-02-26 18:23:43 +01001099def s:Execute()
1100 execute 'help vim9.txt'
1101 let cmd = 'help vim9.txt'
1102 execute cmd
1103 let tag = 'vim9.txt'
1104 execute 'help ' .. tag
1105enddef
1106
1107def Test_disassemble_execute()
1108 let res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001109 assert_match('\<SNR>\d*_Execute\_s*' ..
1110 "execute 'help vim9.txt'\\_s*" ..
1111 '\d PUSHS "help vim9.txt"\_s*' ..
1112 '\d EXECUTE 1\_s*' ..
1113 "let cmd = 'help vim9.txt'\\_s*" ..
1114 '\d PUSHS "help vim9.txt"\_s*' ..
1115 '\d STORE $0\_s*' ..
1116 'execute cmd\_s*' ..
1117 '\d LOAD $0\_s*' ..
1118 '\d EXECUTE 1\_s*' ..
1119 "let tag = 'vim9.txt'\\_s*" ..
1120 '\d PUSHS "vim9.txt"\_s*' ..
1121 '\d STORE $1\_s*' ..
1122 "execute 'help ' .. tag\\_s*" ..
1123 '\d\+ PUSHS "help "\_s*' ..
1124 '\d\+ LOAD $1\_s*' ..
1125 '\d\+ CONCAT\_s*' ..
1126 '\d\+ EXECUTE 1\_s*' ..
1127 '\d\+ PUSHNR 0\_s*' ..
1128 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001129 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01001130enddef
1131
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001132def s:Echomsg()
1133 echomsg 'some' 'message'
1134 echoerr 'went' .. 'wrong'
1135enddef
1136
1137def Test_disassemble_echomsg()
1138 let res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001139 assert_match('\<SNR>\d*_Echomsg\_s*' ..
1140 "echomsg 'some' 'message'\\_s*" ..
1141 '\d PUSHS "some"\_s*' ..
1142 '\d PUSHS "message"\_s*' ..
1143 '\d ECHOMSG 2\_s*' ..
1144 "echoerr 'went' .. 'wrong'\\_s*" ..
1145 '\d PUSHS "wentwrong"\_s*' ..
1146 '\d ECHOERR 1\_s*' ..
1147 '\d PUSHNR 0\_s*' ..
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001148 '\d RETURN',
1149 res)
1150enddef
1151
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001152def SomeStringArg(arg: string)
1153 echo arg
1154enddef
1155
1156def SomeAnyArg(arg: any)
1157 echo arg
1158enddef
1159
1160def SomeStringArgAndReturn(arg: string): string
1161 return arg
1162enddef
1163
1164def Test_display_func()
1165 let res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001166 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
1167 '\d *echo arg.*' ..
1168 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001169 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001170
1171 let res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001172 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
1173 '\d *echo arg\_s*' ..
1174 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001175 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001176
1177 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001178 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
1179 '\d *return arg\_s*' ..
1180 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001181 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001182enddef
1183
Bram Moolenaar09689a02020-05-09 22:50:08 +02001184def Test_vim9script_forward_func()
1185 let lines =<< trim END
1186 vim9script
1187 def FuncOne(): string
1188 return FuncTwo()
1189 enddef
1190 def FuncTwo(): string
1191 return 'two'
1192 enddef
Bram Moolenaar32e35112020-05-14 22:41:15 +02001193 let g:res_FuncOne: string = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02001194 END
1195 writefile(lines, 'Xdisassemble')
1196 source Xdisassemble
1197
1198 " check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001199 assert_match('\<SNR>\d*_FuncOne\_s*' ..
1200 'return FuncTwo()\_s*' ..
1201 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02001202 '\d RETURN',
1203 g:res_FuncOne)
1204
1205 delete('Xdisassemble')
1206 unlet g:res_FuncOne
1207enddef
1208
Bram Moolenaar61a89812020-05-07 16:58:17 +02001209def s:ConcatStrings(): string
1210 return 'one' .. 'two' .. 'three'
1211enddef
1212
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001213def s:ComputeConst(): number
1214 return 2 + 3 * 4 / 6 + 7
1215enddef
1216
Bram Moolenaar1c747212020-05-09 18:28:34 +02001217def s:ComputeConstParen(): number
1218 return ((2 + 4) * (8 / 2)) / (3 + 4)
1219enddef
1220
Bram Moolenaar61a89812020-05-07 16:58:17 +02001221def Test_simplify_const_expr()
1222 let res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001223 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
1224 "return 'one' .. 'two' .. 'three'\\_s*" ..
1225 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02001226 '\d RETURN',
1227 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001228
1229 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001230 assert_match('<SNR>\d*_ComputeConst\_s*' ..
1231 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
1232 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001233 '\d RETURN',
1234 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02001235
1236 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001237 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
1238 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
1239 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02001240 '\d RETURN',
1241 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02001242enddef
1243
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001244" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker