blob: 7fd8c062b195d34cbd69f36a32f6357a1e8ddbac [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 Moolenaar2f8ce0a2020-07-19 19:47:35 +020024 echo get(g:, "global")
Bram Moolenaard3aac292020-04-19 14:32:17 +020025 echo b:buffervar
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020026 echo get(b:, "buffer")
Bram Moolenaard3aac292020-04-19 14:32:17 +020027 echo w:windowvar
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020028 echo get(w:, "window")
Bram Moolenaard3aac292020-04-19 14:32:17 +020029 echo t:tabpagevar
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020030 echo get(t:, "tab")
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010031 echo &tabstop
32 echo $ENVVAR
33 echo @z
34enddef
35
Bram Moolenaarf2460a32020-02-07 22:09:54 +010036def Test_disassemble_load()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010037 assert_fails('disass NoFunc', 'E1061:')
Bram Moolenaar451c2e32020-08-15 16:33:28 +020038 assert_fails('disass NotCompiled', 'E1091:')
Bram Moolenaar21456cd2020-02-13 21:29:32 +010039 assert_fails('disass', 'E471:')
40 assert_fails('disass [', 'E475:')
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +020041 assert_fails('disass 234', 'E129:')
42 assert_fails('disass <XX>foo', 'E129:')
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010043
44 let res = execute('disass s:ScriptFuncLoad')
Bram Moolenaar675f7162020-04-12 22:53:54 +020045 assert_match('<SNR>\d*_ScriptFuncLoad.*' ..
46 'buffers.*' ..
47 ' EXEC \+buffers.*' ..
48 ' LOAD arg\[-1\].*' ..
49 ' LOAD $0.*' ..
Bram Moolenaar8a1c1012020-05-07 14:07:25 +020050 ' LOADOPT &lines.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +020051 ' LOADV v:version.*' ..
52 ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*' ..
53 ' LOADG g:globalvar.*' ..
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020054 'echo get(g:, "global")\_s*' ..
55 '\d\+ LOAD g:\_s*' ..
56 '\d\+ PUSHS "global"\_s*' ..
57 '\d\+ BCALL get(argc 2).*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +020058 ' LOADB b:buffervar.*' ..
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020059 'echo get(b:, "buffer")\_s*' ..
60 '\d\+ LOAD b:\_s*' ..
61 '\d\+ PUSHS "buffer"\_s*' ..
62 '\d\+ BCALL get(argc 2).*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +020063 ' LOADW w:windowvar.*' ..
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020064 'echo get(w:, "window")\_s*' ..
65 '\d\+ LOAD w:\_s*' ..
66 '\d\+ PUSHS "window"\_s*' ..
67 '\d\+ BCALL get(argc 2).*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +020068 ' LOADT t:tabpagevar.*' ..
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020069 'echo get(t:, "tab")\_s*' ..
70 '\d\+ LOAD t:\_s*' ..
71 '\d\+ PUSHS "tab"\_s*' ..
72 '\d\+ BCALL get(argc 2).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +020073 ' LOADENV $ENVVAR.*' ..
74 ' LOADREG @z.*',
75 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010076enddef
77
Bram Moolenaarcfe435d2020-04-25 20:02:55 +020078def s:EditExpand()
79 let filename = "file"
80 let filenr = 123
81 edit the`=filename``=filenr`.txt
82enddef
83
84def Test_disassemble_exec_expr()
85 let res = execute('disass s:EditExpand')
Bram Moolenaar7c5ad342020-08-12 15:48:55 +020086 assert_match('<SNR>\d*_EditExpand\_s*' ..
87 ' let filename = "file"\_s*' ..
88 '\d PUSHS "file"\_s*' ..
89 '\d STORE $0\_s*' ..
90 ' let filenr = 123\_s*' ..
91 '\d STORE 123 in $1\_s*' ..
92 ' edit the`=filename``=filenr`.txt\_s*' ..
93 '\d PUSHS "edit the"\_s*' ..
94 '\d LOAD $0\_s*' ..
95 '\d LOAD $1\_s*' ..
96 '\d 2STRING stack\[-1\]\_s*' ..
97 '\d\+ PUSHS ".txt"\_s*' ..
98 '\d\+ EXECCONCAT 4\_s*' ..
99 '\d\+ PUSHNR 0\_s*' ..
100 '\d\+ RETURN',
101 res)
102enddef
103
104def s:YankRange()
105 norm! m[jjm]
106 :'[,']yank
107enddef
108
109def Test_disassemble_yank_range()
110 let res = execute('disass s:YankRange')
111 assert_match('<SNR>\d*_YankRange.*' ..
112 ' norm! m\[jjm\]\_s*' ..
113 '\d EXEC norm! m\[jjm\]\_s*' ..
114 ' :''\[,''\]yank\_s*' ..
115 '\d EXEC :''\[,''\]yank\_s*' ..
116 '\d PUSHNR 0\_s*' ..
Bram Moolenaarcfe435d2020-04-25 20:02:55 +0200117 '\d RETURN',
118 res)
119enddef
120
Bram Moolenaarc3516f72020-09-08 22:45:35 +0200121def s:PutExpr()
122 :3put ="text"
123enddef
124
125def Test_disassemble_put_expr()
126 let res = execute('disass s:PutExpr')
127 assert_match('<SNR>\d*_PutExpr.*' ..
128 ' :3put ="text"\_s*' ..
129 '\d PUSHS "text"\_s*' ..
130 '\d PUT = 3\_s*' ..
131 '\d PUSHNR 0\_s*' ..
132 '\d RETURN',
133 res)
134enddef
135
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100136def s:ScriptFuncPush()
137 let localbool = true
138 let localspec = v:none
139 let localblob = 0z1234
140 if has('float')
141 let localfloat = 1.234
142 endif
143enddef
144
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100145def Test_disassemble_push()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100146 let res = execute('disass s:ScriptFuncPush')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200147 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
148 'localbool = true.*' ..
149 ' PUSH v:true.*' ..
150 'localspec = v:none.*' ..
151 ' PUSH v:none.*' ..
152 'localblob = 0z1234.*' ..
153 ' PUSHBLOB 0z1234.*',
154 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100155 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200156 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
157 'localfloat = 1.234.*' ..
158 ' PUSHF 1.234.*',
159 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100160 endif
161enddef
162
163def s:ScriptFuncStore()
164 let localnr = 1
165 localnr = 2
166 let localstr = 'abc'
167 localstr = 'xyz'
168 v:char = 'abc'
169 s:scriptvar = 'sv'
170 g:globalvar = 'gv'
Bram Moolenaard3aac292020-04-19 14:32:17 +0200171 b:buffervar = 'bv'
172 w:windowvar = 'wv'
173 t:tabpagevar = 'tv'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100174 &tabstop = 8
175 $ENVVAR = 'ev'
176 @z = 'rv'
177enddef
178
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100179def Test_disassemble_store()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100180 let res = execute('disass s:ScriptFuncStore')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200181 assert_match('<SNR>\d*_ScriptFuncStore.*' ..
182 'let localnr = 1.*' ..
183 'localnr = 2.*' ..
184 ' STORE 2 in $0.*' ..
185 'let localstr = ''abc''.*' ..
186 'localstr = ''xyz''.*' ..
187 ' STORE $1.*' ..
188 'v:char = ''abc''.*' ..
189 'STOREV v:char.*' ..
190 's:scriptvar = ''sv''.*' ..
191 ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
192 'g:globalvar = ''gv''.*' ..
193 ' STOREG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +0200194 'b:buffervar = ''bv''.*' ..
195 ' STOREB b:buffervar.*' ..
196 'w:windowvar = ''wv''.*' ..
197 ' STOREW w:windowvar.*' ..
198 't:tabpagevar = ''tv''.*' ..
199 ' STORET t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200200 '&tabstop = 8.*' ..
201 ' STOREOPT &tabstop.*' ..
202 '$ENVVAR = ''ev''.*' ..
203 ' STOREENV $ENVVAR.*' ..
204 '@z = ''rv''.*' ..
205 ' STOREREG @z.*',
206 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100207enddef
208
Bram Moolenaarcb790402020-05-15 20:53:00 +0200209def s:ScriptFuncStoreMember()
210 let locallist: list<number> = []
211 locallist[0] = 123
212 let localdict: dict<number> = {}
213 localdict["a"] = 456
214enddef
215
216def Test_disassemble_store_member()
217 let res = execute('disass s:ScriptFuncStoreMember')
218 assert_match('<SNR>\d*_ScriptFuncStoreMember\_s*' ..
219 'let locallist: list<number> = []\_s*' ..
220 '\d NEWLIST size 0\_s*' ..
221 '\d STORE $0\_s*' ..
222 'locallist\[0\] = 123\_s*' ..
223 '\d PUSHNR 123\_s*' ..
224 '\d PUSHNR 0\_s*' ..
225 '\d LOAD $0\_s*' ..
226 '\d STORELIST\_s*' ..
227 'let localdict: dict<number> = {}\_s*' ..
228 '\d NEWDICT size 0\_s*' ..
229 '\d STORE $1\_s*' ..
230 'localdict\["a"\] = 456\_s*' ..
231 '\d\+ PUSHNR 456\_s*' ..
232 '\d\+ PUSHS "a"\_s*' ..
233 '\d\+ LOAD $1\_s*' ..
234 '\d\+ STOREDICT\_s*' ..
235 '\d\+ PUSHNR 0\_s*' ..
236 '\d\+ RETURN',
237 res)
238enddef
239
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200240def s:ListAssign()
241 let x: string
242 let y: string
243 let l: list<any>
244 [x, y; l] = g:stringlist
245enddef
246
247def Test_disassemble_list_assign()
248 let res = execute('disass s:ListAssign')
249 assert_match('<SNR>\d*_ListAssign\_s*' ..
250 'let x: string\_s*' ..
251 '\d PUSHS "\[NULL\]"\_s*' ..
252 '\d STORE $0\_s*' ..
253 'let y: string\_s*' ..
254 '\d PUSHS "\[NULL\]"\_s*' ..
255 '\d STORE $1\_s*' ..
256 'let l: list<any>\_s*' ..
257 '\d NEWLIST size 0\_s*' ..
258 '\d STORE $2\_s*' ..
259 '\[x, y; l\] = g:stringlist\_s*' ..
260 '\d LOADG g:stringlist\_s*' ..
Bram Moolenaar5e654232020-09-16 15:22:00 +0200261 '\d CHECKTYPE list<any> stack\[-1\]\_s*' ..
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200262 '\d CHECKLEN >= 2\_s*' ..
263 '\d\+ ITEM 0\_s*' ..
264 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
265 '\d\+ STORE $0\_s*' ..
266 '\d\+ ITEM 1\_s*' ..
267 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
268 '\d\+ STORE $1\_s*' ..
269 '\d\+ SLICE 2\_s*' ..
270 '\d\+ STORE $2\_s*' ..
271 '\d\+ PUSHNR 0\_s*' ..
272 '\d\+ RETURN',
273 res)
274enddef
275
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200276def s:ScriptFuncUnlet()
277 g:somevar = "value"
278 unlet g:somevar
279 unlet! g:somevar
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200280 unlet $SOMEVAR
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200281enddef
282
283def Test_disassemble_unlet()
284 let res = execute('disass s:ScriptFuncUnlet')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200285 assert_match('<SNR>\d*_ScriptFuncUnlet\_s*' ..
286 'g:somevar = "value"\_s*' ..
287 '\d PUSHS "value"\_s*' ..
288 '\d STOREG g:somevar\_s*' ..
289 'unlet g:somevar\_s*' ..
290 '\d UNLET g:somevar\_s*' ..
291 'unlet! g:somevar\_s*' ..
292 '\d UNLET! g:somevar\_s*' ..
293 'unlet $SOMEVAR\_s*' ..
294 '\d UNLETENV $SOMEVAR\_s*',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200295 res)
296enddef
297
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100298def s:ScriptFuncTry()
299 try
Bram Moolenaarcb790402020-05-15 20:53:00 +0200300 echo "yes"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100301 catch /fail/
Bram Moolenaarcb790402020-05-15 20:53:00 +0200302 echo "no"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100303 finally
Bram Moolenaarcb790402020-05-15 20:53:00 +0200304 throw "end"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100305 endtry
306enddef
307
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100308def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100309 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200310 assert_match('<SNR>\d*_ScriptFuncTry\_s*' ..
311 'try\_s*' ..
312 '\d TRY catch -> \d\+, finally -> \d\+\_s*' ..
313 'echo "yes"\_s*' ..
314 '\d PUSHS "yes"\_s*' ..
315 '\d ECHO 1\_s*' ..
316 'catch /fail/\_s*' ..
317 '\d JUMP -> \d\+\_s*' ..
318 '\d PUSH v:exception\_s*' ..
319 '\d PUSHS "fail"\_s*' ..
320 '\d COMPARESTRING =\~\_s*' ..
321 '\d JUMP_IF_FALSE -> \d\+\_s*' ..
322 '\d CATCH\_s*' ..
323 'echo "no"\_s*' ..
324 '\d\+ PUSHS "no"\_s*' ..
325 '\d\+ ECHO 1\_s*' ..
326 'finally\_s*' ..
327 'throw "end"\_s*' ..
328 '\d\+ PUSHS "end"\_s*' ..
329 '\d\+ THROW\_s*' ..
330 'endtry\_s*' ..
331 '\d\+ ENDTRY',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200332 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100333enddef
334
335def s:ScriptFuncNew()
336 let ll = [1, "two", 333]
337 let dd = #{one: 1, two: "val"}
338enddef
339
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100340def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100341 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200342 assert_match('<SNR>\d*_ScriptFuncNew\_s*' ..
343 'let ll = \[1, "two", 333\]\_s*' ..
344 '\d PUSHNR 1\_s*' ..
345 '\d PUSHS "two"\_s*' ..
346 '\d PUSHNR 333\_s*' ..
347 '\d NEWLIST size 3\_s*' ..
348 '\d STORE $0\_s*' ..
349 'let dd = #{one: 1, two: "val"}\_s*' ..
350 '\d PUSHS "one"\_s*' ..
351 '\d PUSHNR 1\_s*' ..
352 '\d PUSHS "two"\_s*' ..
353 '\d PUSHS "val"\_s*' ..
354 '\d NEWDICT size 2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200355 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100356enddef
357
Bram Moolenaar6e949782020-04-13 17:21:00 +0200358def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100359 echo arg
360enddef
361
362func UserFunc()
363 echo 'nothing'
364endfunc
365
366func UserFuncWithArg(arg)
367 echo a:arg
368endfunc
369
370def s:ScriptFuncCall(): string
371 changenr()
372 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100373 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100374 FuncWithArg(343)
375 ScriptFuncNew()
376 s:ScriptFuncNew()
377 UserFunc()
378 UserFuncWithArg("foo")
379 let FuncRef = function("UserFunc")
380 FuncRef()
381 let FuncRefWithArg = function("UserFuncWithArg")
382 FuncRefWithArg("bar")
383 return "yes"
384enddef
385
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100386def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100387 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200388 assert_match('<SNR>\d\+_ScriptFuncCall\_s*' ..
389 'changenr()\_s*' ..
390 '\d BCALL changenr(argc 0)\_s*' ..
391 '\d DROP\_s*' ..
392 'char2nr("abc")\_s*' ..
393 '\d PUSHS "abc"\_s*' ..
394 '\d BCALL char2nr(argc 1)\_s*' ..
395 '\d DROP\_s*' ..
396 'Test_disassemble_new()\_s*' ..
397 '\d DCALL Test_disassemble_new(argc 0)\_s*' ..
398 '\d DROP\_s*' ..
399 'FuncWithArg(343)\_s*' ..
400 '\d\+ PUSHNR 343\_s*' ..
401 '\d\+ DCALL FuncWithArg(argc 1)\_s*' ..
402 '\d\+ DROP\_s*' ..
403 'ScriptFuncNew()\_s*' ..
404 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
405 '\d\+ DROP\_s*' ..
406 's:ScriptFuncNew()\_s*' ..
407 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
408 '\d\+ DROP\_s*' ..
409 'UserFunc()\_s*' ..
410 '\d\+ UCALL UserFunc(argc 0)\_s*' ..
411 '\d\+ DROP\_s*' ..
412 'UserFuncWithArg("foo")\_s*' ..
413 '\d\+ PUSHS "foo"\_s*' ..
414 '\d\+ UCALL UserFuncWithArg(argc 1)\_s*' ..
415 '\d\+ DROP\_s*' ..
416 'let FuncRef = function("UserFunc")\_s*' ..
417 '\d\+ PUSHS "UserFunc"\_s*' ..
418 '\d\+ BCALL function(argc 1)\_s*' ..
419 '\d\+ STORE $0\_s*' ..
420 'FuncRef()\_s*' ..
421 '\d\+ LOAD $\d\_s*' ..
422 '\d\+ PCALL (argc 0)\_s*' ..
423 '\d\+ DROP\_s*' ..
424 'let FuncRefWithArg = function("UserFuncWithArg")\_s*' ..
425 '\d\+ PUSHS "UserFuncWithArg"\_s*' ..
426 '\d\+ BCALL function(argc 1)\_s*' ..
427 '\d\+ STORE $1\_s*' ..
428 'FuncRefWithArg("bar")\_s*' ..
429 '\d\+ PUSHS "bar"\_s*' ..
430 '\d\+ LOAD $\d\_s*' ..
431 '\d\+ PCALL (argc 1)\_s*' ..
432 '\d\+ DROP\_s*' ..
433 'return "yes"\_s*' ..
434 '\d\+ PUSHS "yes"\_s*' ..
435 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200436 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100437enddef
438
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200439def s:CreateRefs()
440 let local = 'a'
441 def Append(arg: string)
442 local ..= arg
443 enddef
444 g:Append = Append
445 def Get(): string
446 return local
447 enddef
448 g:Get = Get
449enddef
450
451def Test_disassemble_closure()
452 CreateRefs()
453 let res = execute('disass g:Append')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200454 assert_match('<lambda>\d\_s*' ..
455 'local ..= arg\_s*' ..
456 '\d LOADOUTER $0\_s*' ..
457 '\d LOAD arg\[-1\]\_s*' ..
458 '\d CONCAT\_s*' ..
459 '\d STOREOUTER $0\_s*' ..
460 '\d PUSHNR 0\_s*' ..
461 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200462 res)
463
464 res = execute('disass g:Get')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200465 assert_match('<lambda>\d\_s*' ..
466 'return local\_s*' ..
467 '\d LOADOUTER $0\_s*' ..
468 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200469 res)
470
471 unlet g:Append
472 unlet g:Get
473enddef
474
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100475
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200476def EchoArg(arg: string): string
477 return arg
478enddef
479def RefThis(): func
480 return function('EchoArg')
481enddef
482def s:ScriptPCall()
483 RefThis()("text")
484enddef
485
486def Test_disassemble_pcall()
487 let res = execute('disass s:ScriptPCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200488 assert_match('<SNR>\d\+_ScriptPCall\_s*' ..
489 'RefThis()("text")\_s*' ..
490 '\d DCALL RefThis(argc 0)\_s*' ..
491 '\d PUSHS "text"\_s*' ..
492 '\d PCALL top (argc 1)\_s*' ..
493 '\d PCALL end\_s*' ..
494 '\d DROP\_s*' ..
495 '\d PUSHNR 0\_s*' ..
496 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200497 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200498enddef
499
500
Bram Moolenaara26b9702020-04-18 19:53:28 +0200501def s:FuncWithForwardCall(): string
502 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100503enddef
504
505def DefinedLater(arg: string): string
506 return arg
507enddef
508
509def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200510 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200511 assert_match('FuncWithForwardCall\_s*' ..
512 'return g:DefinedLater("yes")\_s*' ..
513 '\d PUSHS "yes"\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200514 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200515 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200516 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100517
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200518 # Calling the function will change UCALL into the faster DCALL
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100519 assert_equal('yes', FuncWithForwardCall())
520
Bram Moolenaara26b9702020-04-18 19:53:28 +0200521 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200522 assert_match('FuncWithForwardCall\_s*' ..
523 'return g:DefinedLater("yes")\_s*' ..
524 '\d PUSHS "yes"\_s*' ..
525 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200526 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200527 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100528enddef
529
530
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100531def FuncWithDefault(arg: string = 'default'): string
532 return arg
533enddef
534
535def Test_disassemble_call_default()
536 let res = execute('disass FuncWithDefault')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200537 assert_match('FuncWithDefault\_s*' ..
538 '\d PUSHS "default"\_s*' ..
539 '\d STORE arg\[-1]\_s*' ..
540 'return arg\_s*' ..
541 '\d LOAD arg\[-1]\_s*' ..
542 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200543 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100544enddef
545
546
Bram Moolenaar158906c2020-02-06 20:39:45 +0100547def HasEval()
548 if has("eval")
549 echo "yes"
550 else
551 echo "no"
552 endif
553enddef
554
555def HasNothing()
556 if has("nothing")
557 echo "yes"
558 else
559 echo "no"
560 endif
561enddef
562
563def HasSomething()
564 if has("nothing")
565 echo "nothing"
566 elseif has("something")
567 echo "something"
568 elseif has("eval")
569 echo "eval"
570 elseif has("less")
571 echo "less"
572 endif
573enddef
574
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100575def Test_disassemble_const_expr()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200576 assert_equal("\nyes", execute('HasEval()'))
Bram Moolenaar158906c2020-02-06 20:39:45 +0100577 let instr = execute('disassemble HasEval')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200578 assert_match('HasEval\_s*' ..
579 'if has("eval")\_s*' ..
580 'echo "yes"\_s*' ..
581 '\d PUSHS "yes"\_s*' ..
582 '\d ECHO 1\_s*' ..
583 'else\_s*' ..
584 'echo "no"\_s*' ..
585 'endif\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200586 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100587 assert_notmatch('JUMP', instr)
588
Bram Moolenaard2c61702020-09-06 15:58:36 +0200589 assert_equal("\nno", execute('HasNothing()'))
Bram Moolenaar158906c2020-02-06 20:39:45 +0100590 instr = execute('disassemble HasNothing')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200591 assert_match('HasNothing\_s*' ..
592 'if has("nothing")\_s*' ..
593 'echo "yes"\_s*' ..
594 'else\_s*' ..
595 'echo "no"\_s*' ..
596 '\d PUSHS "no"\_s*' ..
597 '\d ECHO 1\_s*' ..
598 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200599 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100600 assert_notmatch('PUSHS "yes"', instr)
601 assert_notmatch('JUMP', instr)
602
Bram Moolenaard2c61702020-09-06 15:58:36 +0200603 assert_equal("\neval", execute('HasSomething()'))
Bram Moolenaar158906c2020-02-06 20:39:45 +0100604 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200605 assert_match('HasSomething.*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200606 'if has("nothing")\_s*' ..
607 'echo "nothing"\_s*' ..
608 'elseif has("something")\_s*' ..
609 'echo "something"\_s*' ..
610 'elseif has("eval")\_s*' ..
611 'echo "eval"\_s*' ..
612 '\d PUSHS "eval"\_s*' ..
613 '\d ECHO 1\_s*' ..
614 'elseif has("less").*' ..
615 'echo "less"\_s*' ..
616 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200617 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100618 assert_notmatch('PUSHS "nothing"', instr)
619 assert_notmatch('PUSHS "something"', instr)
620 assert_notmatch('PUSHS "less"', instr)
621 assert_notmatch('JUMP', instr)
622enddef
623
Bram Moolenaarefd88552020-06-18 20:50:10 +0200624def ReturnInIf(): string
625 if g:cond
626 return "yes"
627 else
628 return "no"
629 endif
630enddef
631
632def Test_disassemble_return_in_if()
633 let instr = execute('disassemble ReturnInIf')
634 assert_match('ReturnInIf\_s*' ..
635 'if g:cond\_s*' ..
636 '0 LOADG g:cond\_s*' ..
637 '1 JUMP_IF_FALSE -> 4\_s*' ..
638 'return "yes"\_s*' ..
639 '2 PUSHS "yes"\_s*' ..
640 '3 RETURN\_s*' ..
641 'else\_s*' ..
642 ' return "no"\_s*' ..
643 '4 PUSHS "no"\_s*' ..
644 '5 RETURN$',
645 instr)
646enddef
647
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100648def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200649 let Funky1: func
650 let Funky2: func = function("len")
651 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100652enddef
653
654def Test_disassemble_function()
655 let instr = execute('disassemble WithFunc')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200656 assert_match('WithFunc\_s*' ..
657 'let Funky1: func\_s*' ..
658 '0 PUSHFUNC "\[none]"\_s*' ..
659 '1 STORE $0\_s*' ..
660 'let Funky2: func = function("len")\_s*' ..
661 '2 PUSHS "len"\_s*' ..
662 '3 BCALL function(argc 1)\_s*' ..
663 '4 STORE $1\_s*' ..
664 'let Party2: func = funcref("UserFunc")\_s*' ..
665 '\d PUSHS "UserFunc"\_s*' ..
666 '\d BCALL funcref(argc 1)\_s*' ..
667 '\d STORE $2\_s*' ..
668 '\d PUSHNR 0\_s*' ..
669 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200670 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100671enddef
672
673if has('channel')
674 def WithChannel()
675 let job1: job
676 let job2: job = job_start("donothing")
677 let chan1: channel
678 enddef
679endif
680
681def Test_disassemble_channel()
682 CheckFeature channel
683
684 let instr = execute('disassemble WithChannel')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200685 assert_match('WithChannel\_s*' ..
686 'let job1: job\_s*' ..
687 '\d PUSHJOB "no process"\_s*' ..
688 '\d STORE $0\_s*' ..
689 'let job2: job = job_start("donothing")\_s*' ..
690 '\d PUSHS "donothing"\_s*' ..
691 '\d BCALL job_start(argc 1)\_s*' ..
692 '\d STORE $1\_s*' ..
693 'let chan1: channel\_s*' ..
694 '\d PUSHCHANNEL 0\_s*' ..
695 '\d STORE $2\_s*' ..
696 '\d PUSHNR 0\_s*' ..
697 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200698 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100699enddef
700
Bram Moolenaar777770f2020-02-06 21:27:08 +0100701def WithLambda(): string
702 let F = {a -> "X" .. a .. "X"}
703 return F("x")
704enddef
705
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100706def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100707 assert_equal("XxX", WithLambda())
708 let instr = execute('disassemble WithLambda')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200709 assert_match('WithLambda\_s*' ..
710 'let F = {a -> "X" .. a .. "X"}\_s*' ..
711 '\d FUNCREF <lambda>\d\+ $1\_s*' ..
712 '\d STORE $0\_s*' ..
713 'return F("x")\_s*' ..
714 '\d PUSHS "x"\_s*' ..
715 '\d LOAD $0\_s*' ..
716 '\d PCALL (argc 1)\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200717 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200718 instr)
Bram Moolenaarbfd65582020-07-13 18:18:00 +0200719
720 let name = substitute(instr, '.*\(<lambda>\d\+\).*', '\1', '')
721 instr = execute('disassemble ' .. name)
722 assert_match('<lambda>\d\+\_s*' ..
723 'return "X" .. a .. "X"\_s*' ..
724 '\d PUSHS "X"\_s*' ..
725 '\d LOAD arg\[-1\]\_s*' ..
Bram Moolenaar418f1df2020-08-12 21:34:49 +0200726 '\d 2STRING_ANY stack\[-1\]\_s*' ..
Bram Moolenaarbfd65582020-07-13 18:18:00 +0200727 '\d CONCAT\_s*' ..
728 '\d PUSHS "X"\_s*' ..
729 '\d CONCAT\_s*' ..
730 '\d RETURN',
731 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100732enddef
733
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200734def NestedOuter()
735 def g:Inner()
736 echomsg "inner"
737 enddef
738enddef
739
740def Test_nested_func()
741 let instr = execute('disassemble NestedOuter')
742 assert_match('NestedOuter\_s*' ..
743 'def g:Inner()\_s*' ..
744 'echomsg "inner"\_s*' ..
745 'enddef\_s*' ..
746 '\d NEWFUNC <lambda>\d\+ Inner\_s*' ..
747 '\d PUSHNR 0\_s*' ..
748 '\d RETURN',
749 instr)
750enddef
751
Bram Moolenaar6e949782020-04-13 17:21:00 +0200752def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100753 if arg == 1 && arg != 2 || arg == 4
754 return 'yes'
755 endif
756 return 'no'
757enddef
758
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100759def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100760 assert_equal("yes", AndOr(1))
761 assert_equal("no", AndOr(2))
762 assert_equal("yes", AndOr(4))
763 let instr = execute('disassemble AndOr')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200764 assert_match('AndOr\_s*' ..
765 'if arg == 1 && arg != 2 || arg == 4\_s*' ..
766 '\d LOAD arg\[-1]\_s*' ..
767 '\d PUSHNR 1\_s*' ..
768 '\d COMPAREANY ==\_s*' ..
769 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+\_s*' ..
770 '\d LOAD arg\[-1]\_s*' ..
771 '\d PUSHNR 2\_s*' ..
772 '\d COMPAREANY !=\_s*' ..
773 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+\_s*' ..
774 '\d LOAD arg\[-1]\_s*' ..
775 '\d\+ PUSHNR 4\_s*' ..
776 '\d\+ COMPAREANY ==\_s*' ..
777 '\d\+ JUMP_IF_FALSE -> \d\+',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200778 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100779enddef
780
Bram Moolenaar04d05222020-02-06 22:06:54 +0100781def ForLoop(): list<number>
782 let res: list<number>
783 for i in range(3)
784 res->add(i)
785 endfor
786 return res
787enddef
788
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100789def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100790 assert_equal([0, 1, 2], ForLoop())
791 let instr = execute('disassemble ForLoop')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200792 assert_match('ForLoop\_s*' ..
793 'let res: list<number>\_s*' ..
794 '\d NEWLIST size 0\_s*' ..
795 '\d STORE $0\_s*' ..
796 'for i in range(3)\_s*' ..
797 '\d STORE -1 in $1\_s*' ..
798 '\d PUSHNR 3\_s*' ..
799 '\d BCALL range(argc 1)\_s*' ..
800 '\d FOR $1 -> \d\+\_s*' ..
801 '\d STORE $2\_s*' ..
802 'res->add(i)\_s*' ..
803 '\d LOAD $0\_s*' ..
804 '\d LOAD $2\_s*' ..
805 '\d\+ BCALL add(argc 2)\_s*' ..
806 '\d\+ DROP\_s*' ..
807 'endfor\_s*' ..
808 '\d\+ JUMP -> \d\+\_s*' ..
809 '\d\+ DROP',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200810 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100811enddef
812
Bram Moolenaar0ad3e892020-07-05 21:38:11 +0200813def ForLoopEval(): string
814 let res = ""
815 for str in eval('["one", "two"]')
816 res ..= str
817 endfor
818 return res
819enddef
820
821def Test_disassemble_for_loop_eval()
822 assert_equal('onetwo', ForLoopEval())
823 let instr = execute('disassemble ForLoopEval')
824 assert_match('ForLoopEval\_s*' ..
825 'let res = ""\_s*' ..
826 '\d PUSHS ""\_s*' ..
827 '\d STORE $0\_s*' ..
828 'for str in eval(''\["one", "two"\]'')\_s*' ..
829 '\d STORE -1 in $1\_s*' ..
830 '\d PUSHS "\["one", "two"\]"\_s*' ..
831 '\d BCALL eval(argc 1)\_s*' ..
Bram Moolenaar5e654232020-09-16 15:22:00 +0200832 '\d CHECKTYPE list<any> stack\[-1\]\_s*' ..
Bram Moolenaar0ad3e892020-07-05 21:38:11 +0200833 '\d FOR $1 -> \d\+\_s*' ..
834 '\d STORE $2\_s*' ..
835 'res ..= str\_s*' ..
836 '\d\+ LOAD $0\_s*' ..
837 '\d\+ LOAD $2\_s*' ..
838 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
839 '\d\+ CONCAT\_s*' ..
840 '\d\+ STORE $0\_s*' ..
841 'endfor\_s*' ..
842 '\d\+ JUMP -> 6\_s*' ..
843 '\d\+ DROP\_s*' ..
844 'return res\_s*' ..
845 '\d\+ LOAD $0\_s*' ..
846 '\d\+ RETURN',
847 instr)
848enddef
849
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100850let g:number = 42
851
Bram Moolenaar64d662d2020-08-09 19:02:50 +0200852def TypeCast()
853 let l: list<number> = [23, <number>g:number]
854enddef
855
856def Test_disassemble_typecast()
857 let instr = execute('disassemble TypeCast')
858 assert_match('TypeCast.*' ..
859 'let l: list<number> = \[23, <number>g:number\].*' ..
860 '\d PUSHNR 23\_s*' ..
861 '\d LOADG g:number\_s*' ..
862 '\d CHECKTYPE number stack\[-1\]\_s*' ..
863 '\d NEWLIST size 2\_s*' ..
864 '\d STORE $0\_s*' ..
865 '\d PUSHNR 0\_s*' ..
866 '\d RETURN\_s*',
867 instr)
868enddef
869
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100870def Computing()
871 let nr = 3
872 let nrres = nr + 7
873 nrres = nr - 7
874 nrres = nr * 7
875 nrres = nr / 7
876 nrres = nr % 7
877
878 let anyres = g:number + 7
879 anyres = g:number - 7
880 anyres = g:number * 7
881 anyres = g:number / 7
882 anyres = g:number % 7
883
884 if has('float')
885 let fl = 3.0
886 let flres = fl + 7.0
887 flres = fl - 7.0
888 flres = fl * 7.0
889 flres = fl / 7.0
890 endif
891enddef
892
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100893def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100894 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200895 assert_match('Computing.*' ..
896 'let nr = 3.*' ..
897 '\d STORE 3 in $0.*' ..
898 'let nrres = nr + 7.*' ..
899 '\d LOAD $0.*' ..
900 '\d PUSHNR 7.*' ..
901 '\d OPNR +.*' ..
902 '\d STORE $1.*' ..
903 'nrres = nr - 7.*' ..
904 '\d OPNR -.*' ..
905 'nrres = nr \* 7.*' ..
906 '\d OPNR \*.*' ..
907 'nrres = nr / 7.*' ..
908 '\d OPNR /.*' ..
909 'nrres = nr % 7.*' ..
910 '\d OPNR %.*' ..
911 'let anyres = g:number + 7.*' ..
912 '\d LOADG g:number.*' ..
913 '\d PUSHNR 7.*' ..
914 '\d OPANY +.*' ..
915 '\d STORE $2.*' ..
916 'anyres = g:number - 7.*' ..
917 '\d OPANY -.*' ..
918 'anyres = g:number \* 7.*' ..
919 '\d OPANY \*.*' ..
920 'anyres = g:number / 7.*' ..
921 '\d OPANY /.*' ..
922 'anyres = g:number % 7.*' ..
923 '\d OPANY %.*',
924 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100925 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200926 assert_match('Computing.*' ..
927 'let fl = 3.0.*' ..
928 '\d PUSHF 3.0.*' ..
929 '\d STORE $3.*' ..
930 'let flres = fl + 7.0.*' ..
931 '\d LOAD $3.*' ..
932 '\d PUSHF 7.0.*' ..
933 '\d OPFLOAT +.*' ..
934 '\d STORE $4.*' ..
935 'flres = fl - 7.0.*' ..
936 '\d OPFLOAT -.*' ..
937 'flres = fl \* 7.0.*' ..
938 '\d OPFLOAT \*.*' ..
939 'flres = fl / 7.0.*' ..
940 '\d OPFLOAT /.*',
941 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100942 endif
943enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100944
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100945def AddListBlob()
946 let reslist = [1, 2] + [3, 4]
947 let resblob = 0z1122 + 0z3344
948enddef
949
950def Test_disassemble_add_list_blob()
951 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200952 assert_match('AddListBlob.*' ..
953 'let reslist = \[1, 2] + \[3, 4].*' ..
954 '\d PUSHNR 1.*' ..
955 '\d PUSHNR 2.*' ..
956 '\d NEWLIST size 2.*' ..
957 '\d PUSHNR 3.*' ..
958 '\d PUSHNR 4.*' ..
959 '\d NEWLIST size 2.*' ..
960 '\d ADDLIST.*' ..
961 '\d STORE $.*.*' ..
962 'let resblob = 0z1122 + 0z3344.*' ..
963 '\d PUSHBLOB 0z1122.*' ..
964 '\d PUSHBLOB 0z3344.*' ..
965 '\d ADDBLOB.*' ..
966 '\d STORE $.*',
967 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100968enddef
969
970let g:aa = 'aa'
971def ConcatString(): string
972 let res = g:aa .. "bb"
973 return res
974enddef
975
976def Test_disassemble_concat()
977 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200978 assert_match('ConcatString.*' ..
979 'let res = g:aa .. "bb".*' ..
980 '\d LOADG g:aa.*' ..
981 '\d PUSHS "bb".*' ..
Bram Moolenaar418f1df2020-08-12 21:34:49 +0200982 '\d 2STRING_ANY stack\[-2].*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200983 '\d CONCAT.*' ..
984 '\d STORE $.*',
985 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100986 assert_equal('aabb', ConcatString())
987enddef
988
Bram Moolenaar11107ba2020-08-15 21:10:16 +0200989def StringIndex(): string
Bram Moolenaar747f11a2020-07-19 18:38:37 +0200990 let s = "abcd"
991 let res = s[1]
992 return res
993enddef
994
995def Test_disassemble_string_index()
996 let instr = execute('disassemble StringIndex')
997 assert_match('StringIndex\_s*' ..
998 'let s = "abcd"\_s*' ..
999 '\d PUSHS "abcd"\_s*' ..
1000 '\d STORE $0\_s*' ..
1001 'let res = s\[1]\_s*' ..
1002 '\d LOAD $0\_s*' ..
1003 '\d PUSHNR 1\_s*' ..
1004 '\d STRINDEX\_s*' ..
1005 '\d STORE $1\_s*',
1006 instr)
1007 assert_equal('b', StringIndex())
1008enddef
1009
Bram Moolenaared591872020-08-15 22:14:53 +02001010def StringSlice(): string
1011 let s = "abcd"
1012 let res = s[1:8]
1013 return res
1014enddef
1015
1016def Test_disassemble_string_slice()
1017 let instr = execute('disassemble StringSlice')
1018 assert_match('StringSlice\_s*' ..
1019 'let s = "abcd"\_s*' ..
1020 '\d PUSHS "abcd"\_s*' ..
1021 '\d STORE $0\_s*' ..
1022 'let res = s\[1:8]\_s*' ..
1023 '\d LOAD $0\_s*' ..
1024 '\d PUSHNR 1\_s*' ..
1025 '\d PUSHNR 8\_s*' ..
1026 '\d STRSLICE\_s*' ..
1027 '\d STORE $1\_s*',
1028 instr)
1029 assert_equal('bcd', StringSlice())
1030enddef
1031
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001032def ListIndex(): number
1033 let l = [1, 2, 3]
1034 let res = l[1]
1035 return res
1036enddef
1037
1038def Test_disassemble_list_index()
1039 let instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001040 assert_match('ListIndex\_s*' ..
1041 'let l = \[1, 2, 3]\_s*' ..
1042 '\d PUSHNR 1\_s*' ..
1043 '\d PUSHNR 2\_s*' ..
1044 '\d PUSHNR 3\_s*' ..
1045 '\d NEWLIST size 3\_s*' ..
1046 '\d STORE $0\_s*' ..
1047 'let res = l\[1]\_s*' ..
1048 '\d LOAD $0\_s*' ..
1049 '\d PUSHNR 1\_s*' ..
Bram Moolenaar747f11a2020-07-19 18:38:37 +02001050 '\d LISTINDEX\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001051 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001052 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001053 assert_equal(2, ListIndex())
1054enddef
1055
Bram Moolenaared591872020-08-15 22:14:53 +02001056def ListSlice(): list<number>
1057 let l = [1, 2, 3]
1058 let res = l[1:8]
1059 return res
1060enddef
1061
1062def Test_disassemble_list_slice()
1063 let instr = execute('disassemble ListSlice')
1064 assert_match('ListSlice\_s*' ..
1065 'let l = \[1, 2, 3]\_s*' ..
1066 '\d PUSHNR 1\_s*' ..
1067 '\d PUSHNR 2\_s*' ..
1068 '\d PUSHNR 3\_s*' ..
1069 '\d NEWLIST size 3\_s*' ..
1070 '\d STORE $0\_s*' ..
1071 'let res = l\[1:8]\_s*' ..
1072 '\d LOAD $0\_s*' ..
1073 '\d PUSHNR 1\_s*' ..
1074 '\d PUSHNR 8\_s*' ..
1075 '\d LISTSLICE\_s*' ..
1076 '\d STORE $1\_s*',
1077 instr)
1078 assert_equal([2, 3], ListSlice())
1079enddef
1080
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001081def DictMember(): number
1082 let d = #{item: 1}
1083 let res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001084 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001085 return res
1086enddef
1087
1088def Test_disassemble_dict_member()
1089 let instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001090 assert_match('DictMember\_s*' ..
1091 'let d = #{item: 1}\_s*' ..
1092 '\d PUSHS "item"\_s*' ..
1093 '\d PUSHNR 1\_s*' ..
1094 '\d NEWDICT size 1\_s*' ..
1095 '\d STORE $0\_s*' ..
1096 'let res = d.item\_s*' ..
1097 '\d\+ LOAD $0\_s*' ..
1098 '\d\+ MEMBER item\_s*' ..
1099 '\d\+ STORE $1\_s*' ..
1100 'res = d\["item"\]\_s*' ..
1101 '\d\+ LOAD $0\_s*' ..
1102 '\d\+ PUSHS "item"\_s*' ..
1103 '\d\+ MEMBER\_s*' ..
1104 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001105 instr)
Bram Moolenaard2c61702020-09-06 15:58:36 +02001106 assert_equal(1, DictMember())
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001107enddef
1108
Bram Moolenaarcc673e72020-08-16 17:33:35 +02001109let somelist = [1, 2, 3, 4, 5]
1110def AnyIndex(): number
1111 let res = g:somelist[2]
1112 return res
1113enddef
1114
1115def Test_disassemble_any_index()
1116 let instr = execute('disassemble AnyIndex')
1117 assert_match('AnyIndex\_s*' ..
1118 'let res = g:somelist\[2\]\_s*' ..
1119 '\d LOADG g:somelist\_s*' ..
1120 '\d PUSHNR 2\_s*' ..
1121 '\d ANYINDEX\_s*' ..
1122 '\d STORE $0\_s*' ..
1123 'return res\_s*' ..
1124 '\d LOAD $0\_s*' ..
1125 '\d CHECKTYPE number stack\[-1\]\_s*' ..
1126 '\d RETURN',
1127 instr)
1128 assert_equal(3, AnyIndex())
1129enddef
1130
1131def AnySlice(): list<number>
1132 let res = g:somelist[1:3]
1133 return res
1134enddef
1135
1136def Test_disassemble_any_slice()
1137 let instr = execute('disassemble AnySlice')
1138 assert_match('AnySlice\_s*' ..
1139 'let res = g:somelist\[1:3\]\_s*' ..
1140 '\d LOADG g:somelist\_s*' ..
1141 '\d PUSHNR 1\_s*' ..
1142 '\d PUSHNR 3\_s*' ..
1143 '\d ANYSLICE\_s*' ..
1144 '\d STORE $0\_s*' ..
1145 'return res\_s*' ..
1146 '\d LOAD $0\_s*' ..
Bram Moolenaar5e654232020-09-16 15:22:00 +02001147 '\d CHECKTYPE list<number> stack\[-1\]\_s*' ..
Bram Moolenaarcc673e72020-08-16 17:33:35 +02001148 '\d RETURN',
1149 instr)
1150 assert_equal([2, 3, 4], AnySlice())
1151enddef
1152
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001153def NegateNumber(): number
1154 let nr = 9
1155 let plus = +nr
1156 let res = -nr
1157 return res
1158enddef
1159
1160def Test_disassemble_negate_number()
1161 let instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001162 assert_match('NegateNumber\_s*' ..
1163 'let nr = 9\_s*' ..
1164 '\d STORE 9 in $0\_s*' ..
1165 'let plus = +nr\_s*' ..
1166 '\d LOAD $0\_s*' ..
1167 '\d CHECKNR\_s*' ..
1168 '\d STORE $1\_s*' ..
1169 'let res = -nr\_s*' ..
1170 '\d LOAD $0\_s*' ..
1171 '\d NEGATENR\_s*' ..
1172 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001173 instr)
Bram Moolenaard2c61702020-09-06 15:58:36 +02001174 assert_equal(-9, NegateNumber())
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001175enddef
1176
1177def InvertBool(): bool
1178 let flag = true
1179 let invert = !flag
1180 let res = !!flag
1181 return res
1182enddef
1183
1184def Test_disassemble_invert_bool()
1185 let instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001186 assert_match('InvertBool\_s*' ..
1187 'let flag = true\_s*' ..
1188 '\d PUSH v:true\_s*' ..
1189 '\d STORE $0\_s*' ..
1190 'let invert = !flag\_s*' ..
1191 '\d LOAD $0\_s*' ..
1192 '\d INVERT (!val)\_s*' ..
1193 '\d STORE $1\_s*' ..
1194 'let res = !!flag\_s*' ..
1195 '\d LOAD $0\_s*' ..
1196 '\d 2BOOL (!!val)\_s*' ..
1197 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001198 instr)
Bram Moolenaard2c61702020-09-06 15:58:36 +02001199 assert_equal(true, InvertBool())
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001200enddef
1201
Bram Moolenaar4ed124c2020-09-09 20:03:46 +02001202def ReturnBool(): bool
1203 let var: bool = "no" && [] || 123
1204 return var
1205enddef
1206
1207def Test_disassemble_return_bool()
1208 let instr = execute('disassemble ReturnBool')
1209 assert_match('ReturnBool\_s*' ..
1210 'let var: bool = "no" && \[\] || 123\_s*' ..
1211 '0 PUSHS "no"\_s*' ..
1212 '1 JUMP_AND_KEEP_IF_FALSE -> 3\_s*' ..
1213 '2 NEWLIST size 0\_s*' ..
1214 '3 JUMP_AND_KEEP_IF_TRUE -> 5\_s*' ..
1215 '4 PUSHNR 123\_s*' ..
1216 '5 2BOOL (!!val)\_s*' ..
1217 '\d STORE $0\_s*' ..
1218 'return var\_s*' ..
1219 '\d LOAD $0\_s*' ..
1220 '\d RETURN',
1221 instr)
1222 assert_equal(true, InvertBool())
1223enddef
1224
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001225def Test_disassemble_compare()
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001226 let cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +02001227 ['true == isFalse', 'COMPAREBOOL =='],
1228 ['true != isFalse', 'COMPAREBOOL !='],
1229 ['v:none == isNull', 'COMPARESPECIAL =='],
1230 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001231
Bram Moolenaara5565e42020-05-09 15:44:01 +02001232 ['111 == aNumber', 'COMPARENR =='],
1233 ['111 != aNumber', 'COMPARENR !='],
1234 ['111 > aNumber', 'COMPARENR >'],
1235 ['111 < aNumber', 'COMPARENR <'],
1236 ['111 >= aNumber', 'COMPARENR >='],
1237 ['111 <= aNumber', 'COMPARENR <='],
1238 ['111 =~ aNumber', 'COMPARENR =\~'],
1239 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001240
Bram Moolenaara5565e42020-05-09 15:44:01 +02001241 ['"xx" != aString', 'COMPARESTRING !='],
1242 ['"xx" > aString', 'COMPARESTRING >'],
1243 ['"xx" < aString', 'COMPARESTRING <'],
1244 ['"xx" >= aString', 'COMPARESTRING >='],
1245 ['"xx" <= aString', 'COMPARESTRING <='],
1246 ['"xx" =~ aString', 'COMPARESTRING =\~'],
1247 ['"xx" !~ aString', 'COMPARESTRING !\~'],
1248 ['"xx" is aString', 'COMPARESTRING is'],
1249 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001250
Bram Moolenaara5565e42020-05-09 15:44:01 +02001251 ['0z11 == aBlob', 'COMPAREBLOB =='],
1252 ['0z11 != aBlob', 'COMPAREBLOB !='],
1253 ['0z11 is aBlob', 'COMPAREBLOB is'],
1254 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001255
Bram Moolenaara5565e42020-05-09 15:44:01 +02001256 ['[1, 2] == aList', 'COMPARELIST =='],
1257 ['[1, 2] != aList', 'COMPARELIST !='],
1258 ['[1, 2] is aList', 'COMPARELIST is'],
1259 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001260
Bram Moolenaara5565e42020-05-09 15:44:01 +02001261 ['#{a: 1} == aDict', 'COMPAREDICT =='],
1262 ['#{a: 1} != aDict', 'COMPAREDICT !='],
1263 ['#{a: 1} is aDict', 'COMPAREDICT is'],
1264 ['#{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001265
1266 ['{->33} == {->44}', 'COMPAREFUNC =='],
1267 ['{->33} != {->44}', 'COMPAREFUNC !='],
1268 ['{->33} is {->44}', 'COMPAREFUNC is'],
1269 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
1270
1271 ['77 == g:xx', 'COMPAREANY =='],
1272 ['77 != g:xx', 'COMPAREANY !='],
1273 ['77 > g:xx', 'COMPAREANY >'],
1274 ['77 < g:xx', 'COMPAREANY <'],
1275 ['77 >= g:xx', 'COMPAREANY >='],
1276 ['77 <= g:xx', 'COMPAREANY <='],
1277 ['77 =~ g:xx', 'COMPAREANY =\~'],
1278 ['77 !~ g:xx', 'COMPAREANY !\~'],
1279 ['77 is g:xx', 'COMPAREANY is'],
1280 ['77 isnot g:xx', 'COMPAREANY isnot'],
1281 ]
Bram Moolenaara5565e42020-05-09 15:44:01 +02001282 let floatDecl = ''
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001283 if has('float')
1284 cases->extend([
Bram Moolenaara5565e42020-05-09 15:44:01 +02001285 ['1.1 == aFloat', 'COMPAREFLOAT =='],
1286 ['1.1 != aFloat', 'COMPAREFLOAT !='],
1287 ['1.1 > aFloat', 'COMPAREFLOAT >'],
1288 ['1.1 < aFloat', 'COMPAREFLOAT <'],
1289 ['1.1 >= aFloat', 'COMPAREFLOAT >='],
1290 ['1.1 <= aFloat', 'COMPAREFLOAT <='],
1291 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
1292 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001293 ])
Bram Moolenaara5565e42020-05-09 15:44:01 +02001294 floatDecl = 'let aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001295 endif
1296
1297 let nr = 1
1298 for case in cases
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001299 # declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001300 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaara5565e42020-05-09 15:44:01 +02001301 ' let isFalse = false',
1302 ' let isNull = v:null',
1303 ' let aNumber = 222',
1304 ' let aString = "yy"',
1305 ' let aBlob = 0z22',
1306 ' let aList = [3, 4]',
1307 ' let aDict = #{x: 2}',
1308 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +02001309 ' if ' .. case[0],
1310 ' echo 42'
1311 ' endif',
1312 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001313 source Xdisassemble
1314 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +02001315 assert_match('TestCase' .. nr .. '.*' ..
1316 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1317 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +02001318 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001319 '\d ' .. case[1] .. '.*' ..
1320 '\d JUMP_IF_FALSE -> \d\+.*',
1321 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001322
1323 nr += 1
1324 endfor
1325
Bram Moolenaar22da5592020-03-19 14:52:20 +01001326 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001327enddef
1328
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001329def Test_disassemble_compare_const()
1330 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +02001331 ['"xx" == "yy"', false],
1332 ['"aa" == "aa"', true],
1333 ['has("eval") ? true : false', true],
1334 ['has("asdf") ? true : false', false],
1335 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001336
1337 let nr = 1
1338 for case in cases
1339 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001340 ' if ' .. case[0],
1341 ' echo 42'
1342 ' endif',
1343 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001344 source Xdisassemble
1345 let instr = execute('disassemble TestCase' .. nr)
1346 if case[1]
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001347 # condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02001348 assert_match('TestCase' .. nr .. '.*' ..
1349 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1350 '\d PUSHNR 42.*' ..
1351 '\d ECHO 1.*' ..
1352 '\d PUSHNR 0.*' ..
1353 '\d RETURN.*',
1354 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001355 else
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001356 # condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02001357 assert_match('TestCase' .. nr .. '.*' ..
1358 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
1359 'echo 42[ \n]*' ..
1360 'endif[ \n]*' ..
1361 '\s*\d PUSHNR 0.*' ..
1362 '\d RETURN.*',
1363 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001364 endif
1365
1366 nr += 1
1367 endfor
1368
1369 delete('Xdisassemble')
1370enddef
1371
Bram Moolenaarad39c092020-02-26 18:23:43 +01001372def s:Execute()
1373 execute 'help vim9.txt'
1374 let cmd = 'help vim9.txt'
1375 execute cmd
1376 let tag = 'vim9.txt'
1377 execute 'help ' .. tag
1378enddef
1379
1380def Test_disassemble_execute()
1381 let res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001382 assert_match('\<SNR>\d*_Execute\_s*' ..
1383 "execute 'help vim9.txt'\\_s*" ..
1384 '\d PUSHS "help vim9.txt"\_s*' ..
1385 '\d EXECUTE 1\_s*' ..
1386 "let cmd = 'help vim9.txt'\\_s*" ..
1387 '\d PUSHS "help vim9.txt"\_s*' ..
1388 '\d STORE $0\_s*' ..
1389 'execute cmd\_s*' ..
1390 '\d LOAD $0\_s*' ..
1391 '\d EXECUTE 1\_s*' ..
1392 "let tag = 'vim9.txt'\\_s*" ..
1393 '\d PUSHS "vim9.txt"\_s*' ..
1394 '\d STORE $1\_s*' ..
1395 "execute 'help ' .. tag\\_s*" ..
1396 '\d\+ PUSHS "help "\_s*' ..
1397 '\d\+ LOAD $1\_s*' ..
1398 '\d\+ CONCAT\_s*' ..
1399 '\d\+ EXECUTE 1\_s*' ..
1400 '\d\+ PUSHNR 0\_s*' ..
1401 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001402 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01001403enddef
1404
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001405def s:Echomsg()
1406 echomsg 'some' 'message'
1407 echoerr 'went' .. 'wrong'
1408enddef
1409
1410def Test_disassemble_echomsg()
1411 let res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001412 assert_match('\<SNR>\d*_Echomsg\_s*' ..
1413 "echomsg 'some' 'message'\\_s*" ..
1414 '\d PUSHS "some"\_s*' ..
1415 '\d PUSHS "message"\_s*' ..
1416 '\d ECHOMSG 2\_s*' ..
1417 "echoerr 'went' .. 'wrong'\\_s*" ..
1418 '\d PUSHS "wentwrong"\_s*' ..
1419 '\d ECHOERR 1\_s*' ..
1420 '\d PUSHNR 0\_s*' ..
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001421 '\d RETURN',
1422 res)
1423enddef
1424
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001425def SomeStringArg(arg: string)
1426 echo arg
1427enddef
1428
1429def SomeAnyArg(arg: any)
1430 echo arg
1431enddef
1432
1433def SomeStringArgAndReturn(arg: string): string
1434 return arg
1435enddef
1436
1437def Test_display_func()
1438 let res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001439 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
1440 '\d *echo arg.*' ..
1441 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001442 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001443
1444 let res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001445 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
1446 '\d *echo arg\_s*' ..
1447 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001448 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001449
1450 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001451 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
1452 '\d *return arg\_s*' ..
1453 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001454 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001455enddef
1456
Bram Moolenaar09689a02020-05-09 22:50:08 +02001457def Test_vim9script_forward_func()
1458 let lines =<< trim END
1459 vim9script
1460 def FuncOne(): string
1461 return FuncTwo()
1462 enddef
1463 def FuncTwo(): string
1464 return 'two'
1465 enddef
Bram Moolenaar67979662020-06-20 22:50:47 +02001466 g:res_FuncOne = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02001467 END
1468 writefile(lines, 'Xdisassemble')
1469 source Xdisassemble
1470
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001471 # check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001472 assert_match('\<SNR>\d*_FuncOne\_s*' ..
1473 'return FuncTwo()\_s*' ..
1474 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02001475 '\d RETURN',
1476 g:res_FuncOne)
1477
1478 delete('Xdisassemble')
1479 unlet g:res_FuncOne
1480enddef
1481
Bram Moolenaar61a89812020-05-07 16:58:17 +02001482def s:ConcatStrings(): string
1483 return 'one' .. 'two' .. 'three'
1484enddef
1485
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001486def s:ComputeConst(): number
1487 return 2 + 3 * 4 / 6 + 7
1488enddef
1489
Bram Moolenaar1c747212020-05-09 18:28:34 +02001490def s:ComputeConstParen(): number
1491 return ((2 + 4) * (8 / 2)) / (3 + 4)
1492enddef
1493
Bram Moolenaar61a89812020-05-07 16:58:17 +02001494def Test_simplify_const_expr()
1495 let res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001496 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
1497 "return 'one' .. 'two' .. 'three'\\_s*" ..
1498 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02001499 '\d RETURN',
1500 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001501
1502 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001503 assert_match('<SNR>\d*_ComputeConst\_s*' ..
1504 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
1505 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001506 '\d RETURN',
1507 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02001508
1509 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001510 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
1511 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
1512 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02001513 '\d RETURN',
1514 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02001515enddef
1516
Bram Moolenaar389df252020-07-09 21:20:47 +02001517def s:CallAppend()
1518 eval "some text"->append(2)
1519enddef
1520
1521def Test_shuffle()
1522 let res = execute('disass s:CallAppend')
1523 assert_match('<SNR>\d*_CallAppend\_s*' ..
1524 'eval "some text"->append(2)\_s*' ..
1525 '\d PUSHS "some text"\_s*' ..
1526 '\d PUSHNR 2\_s*' ..
1527 '\d SHUFFLE 2 up 1\_s*' ..
1528 '\d BCALL append(argc 2)\_s*' ..
1529 '\d DROP\_s*' ..
1530 '\d PUSHNR 0\_s*' ..
1531 '\d RETURN',
1532 res)
1533enddef
1534
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001535" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker