blob: 3ed36f3f8613c56ac8f6e49b8dce6a3cd00c5ab4 [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 Moolenaar5cab73f2020-02-06 19:25:19 +0100121def s:ScriptFuncPush()
122 let localbool = true
123 let localspec = v:none
124 let localblob = 0z1234
125 if has('float')
126 let localfloat = 1.234
127 endif
128enddef
129
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100130def Test_disassemble_push()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100131 let res = execute('disass s:ScriptFuncPush')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200132 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
133 'localbool = true.*' ..
134 ' PUSH v:true.*' ..
135 'localspec = v:none.*' ..
136 ' PUSH v:none.*' ..
137 'localblob = 0z1234.*' ..
138 ' PUSHBLOB 0z1234.*',
139 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100140 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200141 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
142 'localfloat = 1.234.*' ..
143 ' PUSHF 1.234.*',
144 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100145 endif
146enddef
147
148def s:ScriptFuncStore()
149 let localnr = 1
150 localnr = 2
151 let localstr = 'abc'
152 localstr = 'xyz'
153 v:char = 'abc'
154 s:scriptvar = 'sv'
155 g:globalvar = 'gv'
Bram Moolenaard3aac292020-04-19 14:32:17 +0200156 b:buffervar = 'bv'
157 w:windowvar = 'wv'
158 t:tabpagevar = 'tv'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100159 &tabstop = 8
160 $ENVVAR = 'ev'
161 @z = 'rv'
162enddef
163
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100164def Test_disassemble_store()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100165 let res = execute('disass s:ScriptFuncStore')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200166 assert_match('<SNR>\d*_ScriptFuncStore.*' ..
167 'let localnr = 1.*' ..
168 'localnr = 2.*' ..
169 ' STORE 2 in $0.*' ..
170 'let localstr = ''abc''.*' ..
171 'localstr = ''xyz''.*' ..
172 ' STORE $1.*' ..
173 'v:char = ''abc''.*' ..
174 'STOREV v:char.*' ..
175 's:scriptvar = ''sv''.*' ..
176 ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
177 'g:globalvar = ''gv''.*' ..
178 ' STOREG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +0200179 'b:buffervar = ''bv''.*' ..
180 ' STOREB b:buffervar.*' ..
181 'w:windowvar = ''wv''.*' ..
182 ' STOREW w:windowvar.*' ..
183 't:tabpagevar = ''tv''.*' ..
184 ' STORET t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200185 '&tabstop = 8.*' ..
186 ' STOREOPT &tabstop.*' ..
187 '$ENVVAR = ''ev''.*' ..
188 ' STOREENV $ENVVAR.*' ..
189 '@z = ''rv''.*' ..
190 ' STOREREG @z.*',
191 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100192enddef
193
Bram Moolenaarcb790402020-05-15 20:53:00 +0200194def s:ScriptFuncStoreMember()
195 let locallist: list<number> = []
196 locallist[0] = 123
197 let localdict: dict<number> = {}
198 localdict["a"] = 456
199enddef
200
201def Test_disassemble_store_member()
202 let res = execute('disass s:ScriptFuncStoreMember')
203 assert_match('<SNR>\d*_ScriptFuncStoreMember\_s*' ..
204 'let locallist: list<number> = []\_s*' ..
205 '\d NEWLIST size 0\_s*' ..
206 '\d STORE $0\_s*' ..
207 'locallist\[0\] = 123\_s*' ..
208 '\d PUSHNR 123\_s*' ..
209 '\d PUSHNR 0\_s*' ..
210 '\d LOAD $0\_s*' ..
211 '\d STORELIST\_s*' ..
212 'let localdict: dict<number> = {}\_s*' ..
213 '\d NEWDICT size 0\_s*' ..
214 '\d STORE $1\_s*' ..
215 'localdict\["a"\] = 456\_s*' ..
216 '\d\+ PUSHNR 456\_s*' ..
217 '\d\+ PUSHS "a"\_s*' ..
218 '\d\+ LOAD $1\_s*' ..
219 '\d\+ STOREDICT\_s*' ..
220 '\d\+ PUSHNR 0\_s*' ..
221 '\d\+ RETURN',
222 res)
223enddef
224
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200225def s:ListAssign()
226 let x: string
227 let y: string
228 let l: list<any>
229 [x, y; l] = g:stringlist
230enddef
231
232def Test_disassemble_list_assign()
233 let res = execute('disass s:ListAssign')
234 assert_match('<SNR>\d*_ListAssign\_s*' ..
235 'let x: string\_s*' ..
236 '\d PUSHS "\[NULL\]"\_s*' ..
237 '\d STORE $0\_s*' ..
238 'let y: string\_s*' ..
239 '\d PUSHS "\[NULL\]"\_s*' ..
240 '\d STORE $1\_s*' ..
241 'let l: list<any>\_s*' ..
242 '\d NEWLIST size 0\_s*' ..
243 '\d STORE $2\_s*' ..
244 '\[x, y; l\] = g:stringlist\_s*' ..
245 '\d LOADG g:stringlist\_s*' ..
246 '\d CHECKTYPE list stack\[-1\]\_s*' ..
247 '\d CHECKLEN >= 2\_s*' ..
248 '\d\+ ITEM 0\_s*' ..
249 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
250 '\d\+ STORE $0\_s*' ..
251 '\d\+ ITEM 1\_s*' ..
252 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
253 '\d\+ STORE $1\_s*' ..
254 '\d\+ SLICE 2\_s*' ..
255 '\d\+ STORE $2\_s*' ..
256 '\d\+ PUSHNR 0\_s*' ..
257 '\d\+ RETURN',
258 res)
259enddef
260
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200261def s:ScriptFuncUnlet()
262 g:somevar = "value"
263 unlet g:somevar
264 unlet! g:somevar
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200265 unlet $SOMEVAR
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200266enddef
267
268def Test_disassemble_unlet()
269 let res = execute('disass s:ScriptFuncUnlet')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200270 assert_match('<SNR>\d*_ScriptFuncUnlet\_s*' ..
271 'g:somevar = "value"\_s*' ..
272 '\d PUSHS "value"\_s*' ..
273 '\d STOREG g:somevar\_s*' ..
274 'unlet g:somevar\_s*' ..
275 '\d UNLET g:somevar\_s*' ..
276 'unlet! g:somevar\_s*' ..
277 '\d UNLET! g:somevar\_s*' ..
278 'unlet $SOMEVAR\_s*' ..
279 '\d UNLETENV $SOMEVAR\_s*',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200280 res)
281enddef
282
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100283def s:ScriptFuncTry()
284 try
Bram Moolenaarcb790402020-05-15 20:53:00 +0200285 echo "yes"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100286 catch /fail/
Bram Moolenaarcb790402020-05-15 20:53:00 +0200287 echo "no"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100288 finally
Bram Moolenaarcb790402020-05-15 20:53:00 +0200289 throw "end"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100290 endtry
291enddef
292
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100293def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100294 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200295 assert_match('<SNR>\d*_ScriptFuncTry\_s*' ..
296 'try\_s*' ..
297 '\d TRY catch -> \d\+, finally -> \d\+\_s*' ..
298 'echo "yes"\_s*' ..
299 '\d PUSHS "yes"\_s*' ..
300 '\d ECHO 1\_s*' ..
301 'catch /fail/\_s*' ..
302 '\d JUMP -> \d\+\_s*' ..
303 '\d PUSH v:exception\_s*' ..
304 '\d PUSHS "fail"\_s*' ..
305 '\d COMPARESTRING =\~\_s*' ..
306 '\d JUMP_IF_FALSE -> \d\+\_s*' ..
307 '\d CATCH\_s*' ..
308 'echo "no"\_s*' ..
309 '\d\+ PUSHS "no"\_s*' ..
310 '\d\+ ECHO 1\_s*' ..
311 'finally\_s*' ..
312 'throw "end"\_s*' ..
313 '\d\+ PUSHS "end"\_s*' ..
314 '\d\+ THROW\_s*' ..
315 'endtry\_s*' ..
316 '\d\+ ENDTRY',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200317 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100318enddef
319
320def s:ScriptFuncNew()
321 let ll = [1, "two", 333]
322 let dd = #{one: 1, two: "val"}
323enddef
324
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100325def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100326 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200327 assert_match('<SNR>\d*_ScriptFuncNew\_s*' ..
328 'let ll = \[1, "two", 333\]\_s*' ..
329 '\d PUSHNR 1\_s*' ..
330 '\d PUSHS "two"\_s*' ..
331 '\d PUSHNR 333\_s*' ..
332 '\d NEWLIST size 3\_s*' ..
333 '\d STORE $0\_s*' ..
334 'let dd = #{one: 1, two: "val"}\_s*' ..
335 '\d PUSHS "one"\_s*' ..
336 '\d PUSHNR 1\_s*' ..
337 '\d PUSHS "two"\_s*' ..
338 '\d PUSHS "val"\_s*' ..
339 '\d NEWDICT size 2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200340 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100341enddef
342
Bram Moolenaar6e949782020-04-13 17:21:00 +0200343def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100344 echo arg
345enddef
346
347func UserFunc()
348 echo 'nothing'
349endfunc
350
351func UserFuncWithArg(arg)
352 echo a:arg
353endfunc
354
355def s:ScriptFuncCall(): string
356 changenr()
357 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100358 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100359 FuncWithArg(343)
360 ScriptFuncNew()
361 s:ScriptFuncNew()
362 UserFunc()
363 UserFuncWithArg("foo")
364 let FuncRef = function("UserFunc")
365 FuncRef()
366 let FuncRefWithArg = function("UserFuncWithArg")
367 FuncRefWithArg("bar")
368 return "yes"
369enddef
370
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100371def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100372 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200373 assert_match('<SNR>\d\+_ScriptFuncCall\_s*' ..
374 'changenr()\_s*' ..
375 '\d BCALL changenr(argc 0)\_s*' ..
376 '\d DROP\_s*' ..
377 'char2nr("abc")\_s*' ..
378 '\d PUSHS "abc"\_s*' ..
379 '\d BCALL char2nr(argc 1)\_s*' ..
380 '\d DROP\_s*' ..
381 'Test_disassemble_new()\_s*' ..
382 '\d DCALL Test_disassemble_new(argc 0)\_s*' ..
383 '\d DROP\_s*' ..
384 'FuncWithArg(343)\_s*' ..
385 '\d\+ PUSHNR 343\_s*' ..
386 '\d\+ DCALL FuncWithArg(argc 1)\_s*' ..
387 '\d\+ DROP\_s*' ..
388 'ScriptFuncNew()\_s*' ..
389 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
390 '\d\+ DROP\_s*' ..
391 's:ScriptFuncNew()\_s*' ..
392 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
393 '\d\+ DROP\_s*' ..
394 'UserFunc()\_s*' ..
395 '\d\+ UCALL UserFunc(argc 0)\_s*' ..
396 '\d\+ DROP\_s*' ..
397 'UserFuncWithArg("foo")\_s*' ..
398 '\d\+ PUSHS "foo"\_s*' ..
399 '\d\+ UCALL UserFuncWithArg(argc 1)\_s*' ..
400 '\d\+ DROP\_s*' ..
401 'let FuncRef = function("UserFunc")\_s*' ..
402 '\d\+ PUSHS "UserFunc"\_s*' ..
403 '\d\+ BCALL function(argc 1)\_s*' ..
404 '\d\+ STORE $0\_s*' ..
405 'FuncRef()\_s*' ..
406 '\d\+ LOAD $\d\_s*' ..
407 '\d\+ PCALL (argc 0)\_s*' ..
408 '\d\+ DROP\_s*' ..
409 'let FuncRefWithArg = function("UserFuncWithArg")\_s*' ..
410 '\d\+ PUSHS "UserFuncWithArg"\_s*' ..
411 '\d\+ BCALL function(argc 1)\_s*' ..
412 '\d\+ STORE $1\_s*' ..
413 'FuncRefWithArg("bar")\_s*' ..
414 '\d\+ PUSHS "bar"\_s*' ..
415 '\d\+ LOAD $\d\_s*' ..
416 '\d\+ PCALL (argc 1)\_s*' ..
417 '\d\+ DROP\_s*' ..
418 'return "yes"\_s*' ..
419 '\d\+ PUSHS "yes"\_s*' ..
420 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200421 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100422enddef
423
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200424def s:CreateRefs()
425 let local = 'a'
426 def Append(arg: string)
427 local ..= arg
428 enddef
429 g:Append = Append
430 def Get(): string
431 return local
432 enddef
433 g:Get = Get
434enddef
435
436def Test_disassemble_closure()
437 CreateRefs()
438 let res = execute('disass g:Append')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200439 assert_match('<lambda>\d\_s*' ..
440 'local ..= arg\_s*' ..
441 '\d LOADOUTER $0\_s*' ..
442 '\d LOAD arg\[-1\]\_s*' ..
443 '\d CONCAT\_s*' ..
444 '\d STOREOUTER $0\_s*' ..
445 '\d PUSHNR 0\_s*' ..
446 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200447 res)
448
449 res = execute('disass g:Get')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200450 assert_match('<lambda>\d\_s*' ..
451 'return local\_s*' ..
452 '\d LOADOUTER $0\_s*' ..
453 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200454 res)
455
456 unlet g:Append
457 unlet g:Get
458enddef
459
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100460
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200461def EchoArg(arg: string): string
462 return arg
463enddef
464def RefThis(): func
465 return function('EchoArg')
466enddef
467def s:ScriptPCall()
468 RefThis()("text")
469enddef
470
471def Test_disassemble_pcall()
472 let res = execute('disass s:ScriptPCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200473 assert_match('<SNR>\d\+_ScriptPCall\_s*' ..
474 'RefThis()("text")\_s*' ..
475 '\d DCALL RefThis(argc 0)\_s*' ..
476 '\d PUSHS "text"\_s*' ..
477 '\d PCALL top (argc 1)\_s*' ..
478 '\d PCALL end\_s*' ..
479 '\d DROP\_s*' ..
480 '\d PUSHNR 0\_s*' ..
481 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200482 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200483enddef
484
485
Bram Moolenaara26b9702020-04-18 19:53:28 +0200486def s:FuncWithForwardCall(): string
487 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100488enddef
489
490def DefinedLater(arg: string): string
491 return arg
492enddef
493
494def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200495 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200496 assert_match('FuncWithForwardCall\_s*' ..
497 'return g:DefinedLater("yes")\_s*' ..
498 '\d PUSHS "yes"\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200499 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200500 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200501 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100502
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200503 # Calling the function will change UCALL into the faster DCALL
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100504 assert_equal('yes', FuncWithForwardCall())
505
Bram Moolenaara26b9702020-04-18 19:53:28 +0200506 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200507 assert_match('FuncWithForwardCall\_s*' ..
508 'return g:DefinedLater("yes")\_s*' ..
509 '\d PUSHS "yes"\_s*' ..
510 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200511 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200512 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100513enddef
514
515
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100516def FuncWithDefault(arg: string = 'default'): string
517 return arg
518enddef
519
520def Test_disassemble_call_default()
521 let res = execute('disass FuncWithDefault')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200522 assert_match('FuncWithDefault\_s*' ..
523 '\d PUSHS "default"\_s*' ..
524 '\d STORE arg\[-1]\_s*' ..
525 'return arg\_s*' ..
526 '\d LOAD arg\[-1]\_s*' ..
527 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200528 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100529enddef
530
531
Bram Moolenaar158906c2020-02-06 20:39:45 +0100532def HasEval()
533 if has("eval")
534 echo "yes"
535 else
536 echo "no"
537 endif
538enddef
539
540def HasNothing()
541 if has("nothing")
542 echo "yes"
543 else
544 echo "no"
545 endif
546enddef
547
548def HasSomething()
549 if has("nothing")
550 echo "nothing"
551 elseif has("something")
552 echo "something"
553 elseif has("eval")
554 echo "eval"
555 elseif has("less")
556 echo "less"
557 endif
558enddef
559
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100560def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100561 assert_equal("\nyes", execute('call HasEval()'))
562 let instr = execute('disassemble HasEval')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200563 assert_match('HasEval\_s*' ..
564 'if has("eval")\_s*' ..
565 'echo "yes"\_s*' ..
566 '\d PUSHS "yes"\_s*' ..
567 '\d ECHO 1\_s*' ..
568 'else\_s*' ..
569 'echo "no"\_s*' ..
570 'endif\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200571 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100572 assert_notmatch('JUMP', instr)
573
574 assert_equal("\nno", execute('call HasNothing()'))
575 instr = execute('disassemble HasNothing')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200576 assert_match('HasNothing\_s*' ..
577 'if has("nothing")\_s*' ..
578 'echo "yes"\_s*' ..
579 'else\_s*' ..
580 'echo "no"\_s*' ..
581 '\d PUSHS "no"\_s*' ..
582 '\d ECHO 1\_s*' ..
583 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200584 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100585 assert_notmatch('PUSHS "yes"', instr)
586 assert_notmatch('JUMP', instr)
587
588 assert_equal("\neval", execute('call HasSomething()'))
589 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200590 assert_match('HasSomething.*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200591 'if has("nothing")\_s*' ..
592 'echo "nothing"\_s*' ..
593 'elseif has("something")\_s*' ..
594 'echo "something"\_s*' ..
595 'elseif has("eval")\_s*' ..
596 'echo "eval"\_s*' ..
597 '\d PUSHS "eval"\_s*' ..
598 '\d ECHO 1\_s*' ..
599 'elseif has("less").*' ..
600 'echo "less"\_s*' ..
601 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200602 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100603 assert_notmatch('PUSHS "nothing"', instr)
604 assert_notmatch('PUSHS "something"', instr)
605 assert_notmatch('PUSHS "less"', instr)
606 assert_notmatch('JUMP', instr)
607enddef
608
Bram Moolenaarefd88552020-06-18 20:50:10 +0200609def ReturnInIf(): string
610 if g:cond
611 return "yes"
612 else
613 return "no"
614 endif
615enddef
616
617def Test_disassemble_return_in_if()
618 let instr = execute('disassemble ReturnInIf')
619 assert_match('ReturnInIf\_s*' ..
620 'if g:cond\_s*' ..
621 '0 LOADG g:cond\_s*' ..
622 '1 JUMP_IF_FALSE -> 4\_s*' ..
623 'return "yes"\_s*' ..
624 '2 PUSHS "yes"\_s*' ..
625 '3 RETURN\_s*' ..
626 'else\_s*' ..
627 ' return "no"\_s*' ..
628 '4 PUSHS "no"\_s*' ..
629 '5 RETURN$',
630 instr)
631enddef
632
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100633def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200634 let Funky1: func
635 let Funky2: func = function("len")
636 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100637enddef
638
639def Test_disassemble_function()
640 let instr = execute('disassemble WithFunc')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200641 assert_match('WithFunc\_s*' ..
642 'let Funky1: func\_s*' ..
643 '0 PUSHFUNC "\[none]"\_s*' ..
644 '1 STORE $0\_s*' ..
645 'let Funky2: func = function("len")\_s*' ..
646 '2 PUSHS "len"\_s*' ..
647 '3 BCALL function(argc 1)\_s*' ..
648 '4 STORE $1\_s*' ..
649 'let Party2: func = funcref("UserFunc")\_s*' ..
650 '\d PUSHS "UserFunc"\_s*' ..
651 '\d BCALL funcref(argc 1)\_s*' ..
652 '\d STORE $2\_s*' ..
653 '\d PUSHNR 0\_s*' ..
654 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200655 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100656enddef
657
658if has('channel')
659 def WithChannel()
660 let job1: job
661 let job2: job = job_start("donothing")
662 let chan1: channel
663 enddef
664endif
665
666def Test_disassemble_channel()
667 CheckFeature channel
668
669 let instr = execute('disassemble WithChannel')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200670 assert_match('WithChannel\_s*' ..
671 'let job1: job\_s*' ..
672 '\d PUSHJOB "no process"\_s*' ..
673 '\d STORE $0\_s*' ..
674 'let job2: job = job_start("donothing")\_s*' ..
675 '\d PUSHS "donothing"\_s*' ..
676 '\d BCALL job_start(argc 1)\_s*' ..
677 '\d STORE $1\_s*' ..
678 'let chan1: channel\_s*' ..
679 '\d PUSHCHANNEL 0\_s*' ..
680 '\d STORE $2\_s*' ..
681 '\d PUSHNR 0\_s*' ..
682 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200683 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100684enddef
685
Bram Moolenaar777770f2020-02-06 21:27:08 +0100686def WithLambda(): string
687 let F = {a -> "X" .. a .. "X"}
688 return F("x")
689enddef
690
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100691def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100692 assert_equal("XxX", WithLambda())
693 let instr = execute('disassemble WithLambda')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200694 assert_match('WithLambda\_s*' ..
695 'let F = {a -> "X" .. a .. "X"}\_s*' ..
696 '\d FUNCREF <lambda>\d\+ $1\_s*' ..
697 '\d STORE $0\_s*' ..
698 'return F("x")\_s*' ..
699 '\d PUSHS "x"\_s*' ..
700 '\d LOAD $0\_s*' ..
701 '\d PCALL (argc 1)\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200702 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200703 instr)
Bram Moolenaarbfd65582020-07-13 18:18:00 +0200704
705 let name = substitute(instr, '.*\(<lambda>\d\+\).*', '\1', '')
706 instr = execute('disassemble ' .. name)
707 assert_match('<lambda>\d\+\_s*' ..
708 'return "X" .. a .. "X"\_s*' ..
709 '\d PUSHS "X"\_s*' ..
710 '\d LOAD arg\[-1\]\_s*' ..
Bram Moolenaar418f1df2020-08-12 21:34:49 +0200711 '\d 2STRING_ANY stack\[-1\]\_s*' ..
Bram Moolenaarbfd65582020-07-13 18:18:00 +0200712 '\d CONCAT\_s*' ..
713 '\d PUSHS "X"\_s*' ..
714 '\d CONCAT\_s*' ..
715 '\d RETURN',
716 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100717enddef
718
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200719def NestedOuter()
720 def g:Inner()
721 echomsg "inner"
722 enddef
723enddef
724
725def Test_nested_func()
726 let instr = execute('disassemble NestedOuter')
727 assert_match('NestedOuter\_s*' ..
728 'def g:Inner()\_s*' ..
729 'echomsg "inner"\_s*' ..
730 'enddef\_s*' ..
731 '\d NEWFUNC <lambda>\d\+ Inner\_s*' ..
732 '\d PUSHNR 0\_s*' ..
733 '\d RETURN',
734 instr)
735enddef
736
Bram Moolenaar6e949782020-04-13 17:21:00 +0200737def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100738 if arg == 1 && arg != 2 || arg == 4
739 return 'yes'
740 endif
741 return 'no'
742enddef
743
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100744def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100745 assert_equal("yes", AndOr(1))
746 assert_equal("no", AndOr(2))
747 assert_equal("yes", AndOr(4))
748 let instr = execute('disassemble AndOr')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200749 assert_match('AndOr\_s*' ..
750 'if arg == 1 && arg != 2 || arg == 4\_s*' ..
751 '\d LOAD arg\[-1]\_s*' ..
752 '\d PUSHNR 1\_s*' ..
753 '\d COMPAREANY ==\_s*' ..
754 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+\_s*' ..
755 '\d LOAD arg\[-1]\_s*' ..
756 '\d PUSHNR 2\_s*' ..
757 '\d COMPAREANY !=\_s*' ..
758 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+\_s*' ..
759 '\d LOAD arg\[-1]\_s*' ..
760 '\d\+ PUSHNR 4\_s*' ..
761 '\d\+ COMPAREANY ==\_s*' ..
762 '\d\+ JUMP_IF_FALSE -> \d\+',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200763 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100764enddef
765
Bram Moolenaar04d05222020-02-06 22:06:54 +0100766def ForLoop(): list<number>
767 let res: list<number>
768 for i in range(3)
769 res->add(i)
770 endfor
771 return res
772enddef
773
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100774def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100775 assert_equal([0, 1, 2], ForLoop())
776 let instr = execute('disassemble ForLoop')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200777 assert_match('ForLoop\_s*' ..
778 'let res: list<number>\_s*' ..
779 '\d NEWLIST size 0\_s*' ..
780 '\d STORE $0\_s*' ..
781 'for i in range(3)\_s*' ..
782 '\d STORE -1 in $1\_s*' ..
783 '\d PUSHNR 3\_s*' ..
784 '\d BCALL range(argc 1)\_s*' ..
785 '\d FOR $1 -> \d\+\_s*' ..
786 '\d STORE $2\_s*' ..
787 'res->add(i)\_s*' ..
788 '\d LOAD $0\_s*' ..
789 '\d LOAD $2\_s*' ..
790 '\d\+ BCALL add(argc 2)\_s*' ..
791 '\d\+ DROP\_s*' ..
792 'endfor\_s*' ..
793 '\d\+ JUMP -> \d\+\_s*' ..
794 '\d\+ DROP',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200795 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100796enddef
797
Bram Moolenaar0ad3e892020-07-05 21:38:11 +0200798def ForLoopEval(): string
799 let res = ""
800 for str in eval('["one", "two"]')
801 res ..= str
802 endfor
803 return res
804enddef
805
806def Test_disassemble_for_loop_eval()
807 assert_equal('onetwo', ForLoopEval())
808 let instr = execute('disassemble ForLoopEval')
809 assert_match('ForLoopEval\_s*' ..
810 'let res = ""\_s*' ..
811 '\d PUSHS ""\_s*' ..
812 '\d STORE $0\_s*' ..
813 'for str in eval(''\["one", "two"\]'')\_s*' ..
814 '\d STORE -1 in $1\_s*' ..
815 '\d PUSHS "\["one", "two"\]"\_s*' ..
816 '\d BCALL eval(argc 1)\_s*' ..
817 '\d CHECKTYPE list stack\[-1\]\_s*' ..
818 '\d FOR $1 -> \d\+\_s*' ..
819 '\d STORE $2\_s*' ..
820 'res ..= str\_s*' ..
821 '\d\+ LOAD $0\_s*' ..
822 '\d\+ LOAD $2\_s*' ..
823 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
824 '\d\+ CONCAT\_s*' ..
825 '\d\+ STORE $0\_s*' ..
826 'endfor\_s*' ..
827 '\d\+ JUMP -> 6\_s*' ..
828 '\d\+ DROP\_s*' ..
829 'return res\_s*' ..
830 '\d\+ LOAD $0\_s*' ..
831 '\d\+ RETURN',
832 instr)
833enddef
834
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100835let g:number = 42
836
Bram Moolenaar64d662d2020-08-09 19:02:50 +0200837def TypeCast()
838 let l: list<number> = [23, <number>g:number]
839enddef
840
841def Test_disassemble_typecast()
842 let instr = execute('disassemble TypeCast')
843 assert_match('TypeCast.*' ..
844 'let l: list<number> = \[23, <number>g:number\].*' ..
845 '\d PUSHNR 23\_s*' ..
846 '\d LOADG g:number\_s*' ..
847 '\d CHECKTYPE number stack\[-1\]\_s*' ..
848 '\d NEWLIST size 2\_s*' ..
849 '\d STORE $0\_s*' ..
850 '\d PUSHNR 0\_s*' ..
851 '\d RETURN\_s*',
852 instr)
853enddef
854
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100855def Computing()
856 let nr = 3
857 let nrres = nr + 7
858 nrres = nr - 7
859 nrres = nr * 7
860 nrres = nr / 7
861 nrres = nr % 7
862
863 let anyres = g:number + 7
864 anyres = g:number - 7
865 anyres = g:number * 7
866 anyres = g:number / 7
867 anyres = g:number % 7
868
869 if has('float')
870 let fl = 3.0
871 let flres = fl + 7.0
872 flres = fl - 7.0
873 flres = fl * 7.0
874 flres = fl / 7.0
875 endif
876enddef
877
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100878def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100879 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200880 assert_match('Computing.*' ..
881 'let nr = 3.*' ..
882 '\d STORE 3 in $0.*' ..
883 'let nrres = nr + 7.*' ..
884 '\d LOAD $0.*' ..
885 '\d PUSHNR 7.*' ..
886 '\d OPNR +.*' ..
887 '\d STORE $1.*' ..
888 'nrres = nr - 7.*' ..
889 '\d OPNR -.*' ..
890 'nrres = nr \* 7.*' ..
891 '\d OPNR \*.*' ..
892 'nrres = nr / 7.*' ..
893 '\d OPNR /.*' ..
894 'nrres = nr % 7.*' ..
895 '\d OPNR %.*' ..
896 'let anyres = g:number + 7.*' ..
897 '\d LOADG g:number.*' ..
898 '\d PUSHNR 7.*' ..
899 '\d OPANY +.*' ..
900 '\d STORE $2.*' ..
901 'anyres = g:number - 7.*' ..
902 '\d OPANY -.*' ..
903 'anyres = g:number \* 7.*' ..
904 '\d OPANY \*.*' ..
905 'anyres = g:number / 7.*' ..
906 '\d OPANY /.*' ..
907 'anyres = g:number % 7.*' ..
908 '\d OPANY %.*',
909 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100910 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200911 assert_match('Computing.*' ..
912 'let fl = 3.0.*' ..
913 '\d PUSHF 3.0.*' ..
914 '\d STORE $3.*' ..
915 'let flres = fl + 7.0.*' ..
916 '\d LOAD $3.*' ..
917 '\d PUSHF 7.0.*' ..
918 '\d OPFLOAT +.*' ..
919 '\d STORE $4.*' ..
920 'flres = fl - 7.0.*' ..
921 '\d OPFLOAT -.*' ..
922 'flres = fl \* 7.0.*' ..
923 '\d OPFLOAT \*.*' ..
924 'flres = fl / 7.0.*' ..
925 '\d OPFLOAT /.*',
926 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100927 endif
928enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100929
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100930def AddListBlob()
931 let reslist = [1, 2] + [3, 4]
932 let resblob = 0z1122 + 0z3344
933enddef
934
935def Test_disassemble_add_list_blob()
936 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200937 assert_match('AddListBlob.*' ..
938 'let reslist = \[1, 2] + \[3, 4].*' ..
939 '\d PUSHNR 1.*' ..
940 '\d PUSHNR 2.*' ..
941 '\d NEWLIST size 2.*' ..
942 '\d PUSHNR 3.*' ..
943 '\d PUSHNR 4.*' ..
944 '\d NEWLIST size 2.*' ..
945 '\d ADDLIST.*' ..
946 '\d STORE $.*.*' ..
947 'let resblob = 0z1122 + 0z3344.*' ..
948 '\d PUSHBLOB 0z1122.*' ..
949 '\d PUSHBLOB 0z3344.*' ..
950 '\d ADDBLOB.*' ..
951 '\d STORE $.*',
952 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100953enddef
954
955let g:aa = 'aa'
956def ConcatString(): string
957 let res = g:aa .. "bb"
958 return res
959enddef
960
961def Test_disassemble_concat()
962 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200963 assert_match('ConcatString.*' ..
964 'let res = g:aa .. "bb".*' ..
965 '\d LOADG g:aa.*' ..
966 '\d PUSHS "bb".*' ..
Bram Moolenaar418f1df2020-08-12 21:34:49 +0200967 '\d 2STRING_ANY stack\[-2].*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200968 '\d CONCAT.*' ..
969 '\d STORE $.*',
970 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100971 assert_equal('aabb', ConcatString())
972enddef
973
Bram Moolenaar11107ba2020-08-15 21:10:16 +0200974def StringIndex(): string
Bram Moolenaar747f11a2020-07-19 18:38:37 +0200975 let s = "abcd"
976 let res = s[1]
977 return res
978enddef
979
980def Test_disassemble_string_index()
981 let instr = execute('disassemble StringIndex')
982 assert_match('StringIndex\_s*' ..
983 'let s = "abcd"\_s*' ..
984 '\d PUSHS "abcd"\_s*' ..
985 '\d STORE $0\_s*' ..
986 'let res = s\[1]\_s*' ..
987 '\d LOAD $0\_s*' ..
988 '\d PUSHNR 1\_s*' ..
989 '\d STRINDEX\_s*' ..
990 '\d STORE $1\_s*',
991 instr)
992 assert_equal('b', StringIndex())
993enddef
994
Bram Moolenaared591872020-08-15 22:14:53 +0200995def StringSlice(): string
996 let s = "abcd"
997 let res = s[1:8]
998 return res
999enddef
1000
1001def Test_disassemble_string_slice()
1002 let instr = execute('disassemble StringSlice')
1003 assert_match('StringSlice\_s*' ..
1004 'let s = "abcd"\_s*' ..
1005 '\d PUSHS "abcd"\_s*' ..
1006 '\d STORE $0\_s*' ..
1007 'let res = s\[1:8]\_s*' ..
1008 '\d LOAD $0\_s*' ..
1009 '\d PUSHNR 1\_s*' ..
1010 '\d PUSHNR 8\_s*' ..
1011 '\d STRSLICE\_s*' ..
1012 '\d STORE $1\_s*',
1013 instr)
1014 assert_equal('bcd', StringSlice())
1015enddef
1016
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001017def ListIndex(): number
1018 let l = [1, 2, 3]
1019 let res = l[1]
1020 return res
1021enddef
1022
1023def Test_disassemble_list_index()
1024 let instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001025 assert_match('ListIndex\_s*' ..
1026 'let l = \[1, 2, 3]\_s*' ..
1027 '\d PUSHNR 1\_s*' ..
1028 '\d PUSHNR 2\_s*' ..
1029 '\d PUSHNR 3\_s*' ..
1030 '\d NEWLIST size 3\_s*' ..
1031 '\d STORE $0\_s*' ..
1032 'let res = l\[1]\_s*' ..
1033 '\d LOAD $0\_s*' ..
1034 '\d PUSHNR 1\_s*' ..
Bram Moolenaar747f11a2020-07-19 18:38:37 +02001035 '\d LISTINDEX\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001036 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001037 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001038 assert_equal(2, ListIndex())
1039enddef
1040
Bram Moolenaared591872020-08-15 22:14:53 +02001041def ListSlice(): list<number>
1042 let l = [1, 2, 3]
1043 let res = l[1:8]
1044 return res
1045enddef
1046
1047def Test_disassemble_list_slice()
1048 let instr = execute('disassemble ListSlice')
1049 assert_match('ListSlice\_s*' ..
1050 'let l = \[1, 2, 3]\_s*' ..
1051 '\d PUSHNR 1\_s*' ..
1052 '\d PUSHNR 2\_s*' ..
1053 '\d PUSHNR 3\_s*' ..
1054 '\d NEWLIST size 3\_s*' ..
1055 '\d STORE $0\_s*' ..
1056 'let res = l\[1:8]\_s*' ..
1057 '\d LOAD $0\_s*' ..
1058 '\d PUSHNR 1\_s*' ..
1059 '\d PUSHNR 8\_s*' ..
1060 '\d LISTSLICE\_s*' ..
1061 '\d STORE $1\_s*',
1062 instr)
1063 assert_equal([2, 3], ListSlice())
1064enddef
1065
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001066def DictMember(): number
1067 let d = #{item: 1}
1068 let res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001069 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001070 return res
1071enddef
1072
1073def Test_disassemble_dict_member()
1074 let instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001075 assert_match('DictMember\_s*' ..
1076 'let d = #{item: 1}\_s*' ..
1077 '\d PUSHS "item"\_s*' ..
1078 '\d PUSHNR 1\_s*' ..
1079 '\d NEWDICT size 1\_s*' ..
1080 '\d STORE $0\_s*' ..
1081 'let res = d.item\_s*' ..
1082 '\d\+ LOAD $0\_s*' ..
1083 '\d\+ MEMBER item\_s*' ..
1084 '\d\+ STORE $1\_s*' ..
1085 'res = d\["item"\]\_s*' ..
1086 '\d\+ LOAD $0\_s*' ..
1087 '\d\+ PUSHS "item"\_s*' ..
1088 '\d\+ MEMBER\_s*' ..
1089 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001090 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001091 call assert_equal(1, DictMember())
1092enddef
1093
1094def NegateNumber(): number
1095 let nr = 9
1096 let plus = +nr
1097 let res = -nr
1098 return res
1099enddef
1100
1101def Test_disassemble_negate_number()
1102 let instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001103 assert_match('NegateNumber\_s*' ..
1104 'let nr = 9\_s*' ..
1105 '\d STORE 9 in $0\_s*' ..
1106 'let plus = +nr\_s*' ..
1107 '\d LOAD $0\_s*' ..
1108 '\d CHECKNR\_s*' ..
1109 '\d STORE $1\_s*' ..
1110 'let res = -nr\_s*' ..
1111 '\d LOAD $0\_s*' ..
1112 '\d NEGATENR\_s*' ..
1113 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001114 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001115 call assert_equal(-9, NegateNumber())
1116enddef
1117
1118def InvertBool(): bool
1119 let flag = true
1120 let invert = !flag
1121 let res = !!flag
1122 return res
1123enddef
1124
1125def Test_disassemble_invert_bool()
1126 let instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001127 assert_match('InvertBool\_s*' ..
1128 'let flag = true\_s*' ..
1129 '\d PUSH v:true\_s*' ..
1130 '\d STORE $0\_s*' ..
1131 'let invert = !flag\_s*' ..
1132 '\d LOAD $0\_s*' ..
1133 '\d INVERT (!val)\_s*' ..
1134 '\d STORE $1\_s*' ..
1135 'let res = !!flag\_s*' ..
1136 '\d LOAD $0\_s*' ..
1137 '\d 2BOOL (!!val)\_s*' ..
1138 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001139 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001140 call assert_equal(true, InvertBool())
1141enddef
1142
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001143def Test_disassemble_compare()
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001144 let cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +02001145 ['true == isFalse', 'COMPAREBOOL =='],
1146 ['true != isFalse', 'COMPAREBOOL !='],
1147 ['v:none == isNull', 'COMPARESPECIAL =='],
1148 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001149
Bram Moolenaara5565e42020-05-09 15:44:01 +02001150 ['111 == aNumber', 'COMPARENR =='],
1151 ['111 != aNumber', 'COMPARENR !='],
1152 ['111 > aNumber', 'COMPARENR >'],
1153 ['111 < aNumber', 'COMPARENR <'],
1154 ['111 >= aNumber', 'COMPARENR >='],
1155 ['111 <= aNumber', 'COMPARENR <='],
1156 ['111 =~ aNumber', 'COMPARENR =\~'],
1157 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001158
Bram Moolenaara5565e42020-05-09 15:44:01 +02001159 ['"xx" != aString', 'COMPARESTRING !='],
1160 ['"xx" > aString', 'COMPARESTRING >'],
1161 ['"xx" < aString', 'COMPARESTRING <'],
1162 ['"xx" >= aString', 'COMPARESTRING >='],
1163 ['"xx" <= aString', 'COMPARESTRING <='],
1164 ['"xx" =~ aString', 'COMPARESTRING =\~'],
1165 ['"xx" !~ aString', 'COMPARESTRING !\~'],
1166 ['"xx" is aString', 'COMPARESTRING is'],
1167 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001168
Bram Moolenaara5565e42020-05-09 15:44:01 +02001169 ['0z11 == aBlob', 'COMPAREBLOB =='],
1170 ['0z11 != aBlob', 'COMPAREBLOB !='],
1171 ['0z11 is aBlob', 'COMPAREBLOB is'],
1172 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001173
Bram Moolenaara5565e42020-05-09 15:44:01 +02001174 ['[1, 2] == aList', 'COMPARELIST =='],
1175 ['[1, 2] != aList', 'COMPARELIST !='],
1176 ['[1, 2] is aList', 'COMPARELIST is'],
1177 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001178
Bram Moolenaara5565e42020-05-09 15:44:01 +02001179 ['#{a: 1} == aDict', 'COMPAREDICT =='],
1180 ['#{a: 1} != aDict', 'COMPAREDICT !='],
1181 ['#{a: 1} is aDict', 'COMPAREDICT is'],
1182 ['#{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001183
1184 ['{->33} == {->44}', 'COMPAREFUNC =='],
1185 ['{->33} != {->44}', 'COMPAREFUNC !='],
1186 ['{->33} is {->44}', 'COMPAREFUNC is'],
1187 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
1188
1189 ['77 == g:xx', 'COMPAREANY =='],
1190 ['77 != g:xx', 'COMPAREANY !='],
1191 ['77 > g:xx', 'COMPAREANY >'],
1192 ['77 < g:xx', 'COMPAREANY <'],
1193 ['77 >= g:xx', 'COMPAREANY >='],
1194 ['77 <= g:xx', 'COMPAREANY <='],
1195 ['77 =~ g:xx', 'COMPAREANY =\~'],
1196 ['77 !~ g:xx', 'COMPAREANY !\~'],
1197 ['77 is g:xx', 'COMPAREANY is'],
1198 ['77 isnot g:xx', 'COMPAREANY isnot'],
1199 ]
Bram Moolenaara5565e42020-05-09 15:44:01 +02001200 let floatDecl = ''
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001201 if has('float')
1202 cases->extend([
Bram Moolenaara5565e42020-05-09 15:44:01 +02001203 ['1.1 == aFloat', 'COMPAREFLOAT =='],
1204 ['1.1 != aFloat', 'COMPAREFLOAT !='],
1205 ['1.1 > aFloat', 'COMPAREFLOAT >'],
1206 ['1.1 < aFloat', 'COMPAREFLOAT <'],
1207 ['1.1 >= aFloat', 'COMPAREFLOAT >='],
1208 ['1.1 <= aFloat', 'COMPAREFLOAT <='],
1209 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
1210 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001211 ])
Bram Moolenaara5565e42020-05-09 15:44:01 +02001212 floatDecl = 'let aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001213 endif
1214
1215 let nr = 1
1216 for case in cases
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001217 # declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001218 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaara5565e42020-05-09 15:44:01 +02001219 ' let isFalse = false',
1220 ' let isNull = v:null',
1221 ' let aNumber = 222',
1222 ' let aString = "yy"',
1223 ' let aBlob = 0z22',
1224 ' let aList = [3, 4]',
1225 ' let aDict = #{x: 2}',
1226 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +02001227 ' if ' .. case[0],
1228 ' echo 42'
1229 ' endif',
1230 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001231 source Xdisassemble
1232 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +02001233 assert_match('TestCase' .. nr .. '.*' ..
1234 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1235 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +02001236 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001237 '\d ' .. case[1] .. '.*' ..
1238 '\d JUMP_IF_FALSE -> \d\+.*',
1239 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001240
1241 nr += 1
1242 endfor
1243
Bram Moolenaar22da5592020-03-19 14:52:20 +01001244 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001245enddef
1246
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001247def Test_disassemble_compare_const()
1248 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +02001249 ['"xx" == "yy"', false],
1250 ['"aa" == "aa"', true],
1251 ['has("eval") ? true : false', true],
1252 ['has("asdf") ? true : false', false],
1253 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001254
1255 let nr = 1
1256 for case in cases
1257 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001258 ' if ' .. case[0],
1259 ' echo 42'
1260 ' endif',
1261 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001262 source Xdisassemble
1263 let instr = execute('disassemble TestCase' .. nr)
1264 if case[1]
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001265 # condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02001266 assert_match('TestCase' .. nr .. '.*' ..
1267 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1268 '\d PUSHNR 42.*' ..
1269 '\d ECHO 1.*' ..
1270 '\d PUSHNR 0.*' ..
1271 '\d RETURN.*',
1272 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001273 else
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001274 # condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02001275 assert_match('TestCase' .. nr .. '.*' ..
1276 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
1277 'echo 42[ \n]*' ..
1278 'endif[ \n]*' ..
1279 '\s*\d PUSHNR 0.*' ..
1280 '\d RETURN.*',
1281 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001282 endif
1283
1284 nr += 1
1285 endfor
1286
1287 delete('Xdisassemble')
1288enddef
1289
Bram Moolenaarad39c092020-02-26 18:23:43 +01001290def s:Execute()
1291 execute 'help vim9.txt'
1292 let cmd = 'help vim9.txt'
1293 execute cmd
1294 let tag = 'vim9.txt'
1295 execute 'help ' .. tag
1296enddef
1297
1298def Test_disassemble_execute()
1299 let res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001300 assert_match('\<SNR>\d*_Execute\_s*' ..
1301 "execute 'help vim9.txt'\\_s*" ..
1302 '\d PUSHS "help vim9.txt"\_s*' ..
1303 '\d EXECUTE 1\_s*' ..
1304 "let cmd = 'help vim9.txt'\\_s*" ..
1305 '\d PUSHS "help vim9.txt"\_s*' ..
1306 '\d STORE $0\_s*' ..
1307 'execute cmd\_s*' ..
1308 '\d LOAD $0\_s*' ..
1309 '\d EXECUTE 1\_s*' ..
1310 "let tag = 'vim9.txt'\\_s*" ..
1311 '\d PUSHS "vim9.txt"\_s*' ..
1312 '\d STORE $1\_s*' ..
1313 "execute 'help ' .. tag\\_s*" ..
1314 '\d\+ PUSHS "help "\_s*' ..
1315 '\d\+ LOAD $1\_s*' ..
1316 '\d\+ CONCAT\_s*' ..
1317 '\d\+ EXECUTE 1\_s*' ..
1318 '\d\+ PUSHNR 0\_s*' ..
1319 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001320 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01001321enddef
1322
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001323def s:Echomsg()
1324 echomsg 'some' 'message'
1325 echoerr 'went' .. 'wrong'
1326enddef
1327
1328def Test_disassemble_echomsg()
1329 let res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001330 assert_match('\<SNR>\d*_Echomsg\_s*' ..
1331 "echomsg 'some' 'message'\\_s*" ..
1332 '\d PUSHS "some"\_s*' ..
1333 '\d PUSHS "message"\_s*' ..
1334 '\d ECHOMSG 2\_s*' ..
1335 "echoerr 'went' .. 'wrong'\\_s*" ..
1336 '\d PUSHS "wentwrong"\_s*' ..
1337 '\d ECHOERR 1\_s*' ..
1338 '\d PUSHNR 0\_s*' ..
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001339 '\d RETURN',
1340 res)
1341enddef
1342
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001343def SomeStringArg(arg: string)
1344 echo arg
1345enddef
1346
1347def SomeAnyArg(arg: any)
1348 echo arg
1349enddef
1350
1351def SomeStringArgAndReturn(arg: string): string
1352 return arg
1353enddef
1354
1355def Test_display_func()
1356 let res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001357 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
1358 '\d *echo arg.*' ..
1359 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001360 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001361
1362 let res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001363 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
1364 '\d *echo arg\_s*' ..
1365 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001366 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001367
1368 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001369 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
1370 '\d *return arg\_s*' ..
1371 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001372 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001373enddef
1374
Bram Moolenaar09689a02020-05-09 22:50:08 +02001375def Test_vim9script_forward_func()
1376 let lines =<< trim END
1377 vim9script
1378 def FuncOne(): string
1379 return FuncTwo()
1380 enddef
1381 def FuncTwo(): string
1382 return 'two'
1383 enddef
Bram Moolenaar67979662020-06-20 22:50:47 +02001384 g:res_FuncOne = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02001385 END
1386 writefile(lines, 'Xdisassemble')
1387 source Xdisassemble
1388
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001389 # check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001390 assert_match('\<SNR>\d*_FuncOne\_s*' ..
1391 'return FuncTwo()\_s*' ..
1392 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02001393 '\d RETURN',
1394 g:res_FuncOne)
1395
1396 delete('Xdisassemble')
1397 unlet g:res_FuncOne
1398enddef
1399
Bram Moolenaar61a89812020-05-07 16:58:17 +02001400def s:ConcatStrings(): string
1401 return 'one' .. 'two' .. 'three'
1402enddef
1403
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001404def s:ComputeConst(): number
1405 return 2 + 3 * 4 / 6 + 7
1406enddef
1407
Bram Moolenaar1c747212020-05-09 18:28:34 +02001408def s:ComputeConstParen(): number
1409 return ((2 + 4) * (8 / 2)) / (3 + 4)
1410enddef
1411
Bram Moolenaar61a89812020-05-07 16:58:17 +02001412def Test_simplify_const_expr()
1413 let res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001414 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
1415 "return 'one' .. 'two' .. 'three'\\_s*" ..
1416 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02001417 '\d RETURN',
1418 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001419
1420 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001421 assert_match('<SNR>\d*_ComputeConst\_s*' ..
1422 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
1423 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001424 '\d RETURN',
1425 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02001426
1427 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001428 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
1429 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
1430 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02001431 '\d RETURN',
1432 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02001433enddef
1434
Bram Moolenaar389df252020-07-09 21:20:47 +02001435def s:CallAppend()
1436 eval "some text"->append(2)
1437enddef
1438
1439def Test_shuffle()
1440 let res = execute('disass s:CallAppend')
1441 assert_match('<SNR>\d*_CallAppend\_s*' ..
1442 'eval "some text"->append(2)\_s*' ..
1443 '\d PUSHS "some text"\_s*' ..
1444 '\d PUSHNR 2\_s*' ..
1445 '\d SHUFFLE 2 up 1\_s*' ..
1446 '\d BCALL append(argc 2)\_s*' ..
1447 '\d DROP\_s*' ..
1448 '\d PUSHNR 0\_s*' ..
1449 '\d RETURN',
1450 res)
1451enddef
1452
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001453" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker