blob: b6edb0d6c39c6b65e288866ee67bfc9d9cb2fd11 [file] [log] [blame]
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001" Test the :disassemble command, and compilation as a side effect
2
3func NotCompiled()
4 echo "not"
5endfunc
6
7let s:scriptvar = 4
8let g:globalvar = 'g'
9
10def s:ScriptFuncLoad(arg: string)
11 let local = 1
12 buffers
13 echo arg
14 echo local
15 echo v:version
16 echo s:scriptvar
17 echo g:globalvar
18 echo &tabstop
19 echo $ENVVAR
20 echo @z
21enddef
22
23def Test_disassembleLoad()
24 assert_fails('disass NoFunc', 'E1061:')
25 assert_fails('disass NotCompiled', 'E1062:')
26
27 let res = execute('disass s:ScriptFuncLoad')
28 assert_match('<SNR>\d*_ScriptFuncLoad.*'
29 \ .. 'buffers.*'
30 \ .. ' EXEC \+buffers.*'
31 \ .. ' LOAD arg\[-1\].*'
32 \ .. ' LOAD $0.*'
33 \ .. ' LOADV v:version.*'
34 \ .. ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*'
35 \ .. ' LOADG g:globalvar.*'
36 \ .. ' LOADENV $ENVVAR.*'
37 \ .. ' LOADREG @z.*'
38 \, res)
39enddef
40
41def s:ScriptFuncPush()
42 let localbool = true
43 let localspec = v:none
44 let localblob = 0z1234
45 if has('float')
46 let localfloat = 1.234
47 endif
48enddef
49
50def Test_disassemblePush()
51 let res = execute('disass s:ScriptFuncPush')
52 assert_match('<SNR>\d*_ScriptFuncPush.*'
53 \ .. 'localbool = true.*'
54 \ .. ' PUSH v:true.*'
55 \ .. 'localspec = v:none.*'
56 \ .. ' PUSH v:none.*'
57 \ .. 'localblob = 0z1234.*'
58 \ .. ' PUSHBLOB 0z1234.*'
59 \, res)
60 if has('float')
61 assert_match('<SNR>\d*_ScriptFuncPush.*'
62 \ .. 'localfloat = 1.234.*'
63 \ .. ' PUSHF 1.234.*'
64 \, res)
65 endif
66enddef
67
68def s:ScriptFuncStore()
69 let localnr = 1
70 localnr = 2
71 let localstr = 'abc'
72 localstr = 'xyz'
73 v:char = 'abc'
74 s:scriptvar = 'sv'
75 g:globalvar = 'gv'
76 &tabstop = 8
77 $ENVVAR = 'ev'
78 @z = 'rv'
79enddef
80
81def Test_disassembleStore()
82 let res = execute('disass s:ScriptFuncStore')
83 assert_match('<SNR>\d*_ScriptFuncStore.*'
84 \ .. 'localnr = 2.*'
85 \ .. ' STORE 2 in $0.*'
86 \ .. 'localstr = ''xyz''.*'
87 \ .. ' STORE $1.*'
88 \ .. 'v:char = ''abc''.*'
89 \ .. 'STOREV v:char.*'
90 \ .. 's:scriptvar = ''sv''.*'
91 \ .. ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*'
92 \ .. 'g:globalvar = ''gv''.*'
93 \ .. ' STOREG g:globalvar.*'
94 \ .. '&tabstop = 8.*'
95 \ .. ' STOREOPT &tabstop.*'
96 \ .. '$ENVVAR = ''ev''.*'
97 \ .. ' STOREENV $ENVVAR.*'
98 \ .. '@z = ''rv''.*'
99 \ .. ' STOREREG @z.*'
100 \, res)
101enddef
102
103def s:ScriptFuncTry()
104 try
105 echo 'yes'
106 catch /fail/
107 echo 'no'
108 finally
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100109 throw 'end'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100110 endtry
111enddef
112
113def Test_disassembleTry()
114 let res = execute('disass s:ScriptFuncTry')
115 assert_match('<SNR>\d*_ScriptFuncTry.*'
116 \ .. 'try.*'
117 \ .. 'TRY catch -> \d\+, finally -> \d\+.*'
118 \ .. 'catch /fail/.*'
119 \ .. ' JUMP -> \d\+.*'
120 \ .. ' PUSH v:exception.*'
121 \ .. ' PUSHS "fail".*'
122 \ .. ' COMPARESTRING =\~.*'
123 \ .. ' JUMP_IF_FALSE -> \d\+.*'
124 \ .. ' CATCH.*'
125 \ .. 'finally.*'
126 \ .. ' PUSHS "end".*'
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100127 \ .. ' THROW.*'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100128 \ .. 'endtry.*'
129 \ .. ' ENDTRY.*'
130 \, res)
131enddef
132
133def s:ScriptFuncNew()
134 let ll = [1, "two", 333]
135 let dd = #{one: 1, two: "val"}
136enddef
137
138def Test_disassembleNew()
139 let res = execute('disass s:ScriptFuncNew')
140 assert_match('<SNR>\d*_ScriptFuncNew.*'
141 \ .. 'let ll = \[1, "two", 333].*'
142 \ .. 'PUSHNR 1.*'
143 \ .. 'PUSHS "two".*'
144 \ .. 'PUSHNR 333.*'
145 \ .. 'NEWLIST size 3.*'
146 \ .. 'let dd = #{one: 1, two: "val"}.*'
147 \ .. 'PUSHS "one".*'
148 \ .. 'PUSHNR 1.*'
149 \ .. 'PUSHS "two".*'
150 \ .. 'PUSHS "val".*'
151 \ .. 'NEWDICT size 2.*'
152 \, res)
153enddef
154
155def FuncWithArg(arg)
156 echo arg
157enddef
158
159func UserFunc()
160 echo 'nothing'
161endfunc
162
163func UserFuncWithArg(arg)
164 echo a:arg
165endfunc
166
167def s:ScriptFuncCall(): string
168 changenr()
169 char2nr("abc")
170 Test_disassembleNew()
171 FuncWithArg(343)
172 ScriptFuncNew()
173 s:ScriptFuncNew()
174 UserFunc()
175 UserFuncWithArg("foo")
176 let FuncRef = function("UserFunc")
177 FuncRef()
178 let FuncRefWithArg = function("UserFuncWithArg")
179 FuncRefWithArg("bar")
180 return "yes"
181enddef
182
183def Test_disassembleCall()
184 let res = execute('disass s:ScriptFuncCall')
185 assert_match('<SNR>\d\+_ScriptFuncCall.*'
186 \ .. 'changenr().*'
187 \ .. ' BCALL changenr(argc 0).*'
188 \ .. 'char2nr("abc").*'
189 \ .. ' PUSHS "abc".*'
190 \ .. ' BCALL char2nr(argc 1).*'
191 \ .. 'Test_disassembleNew().*'
192 \ .. ' DCALL Test_disassembleNew(argc 0).*'
193 \ .. 'FuncWithArg(343).*'
194 \ .. ' PUSHNR 343.*'
195 \ .. ' DCALL FuncWithArg(argc 1).*'
196 \ .. 'ScriptFuncNew().*'
197 \ .. ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*'
198 \ .. 's:ScriptFuncNew().*'
199 \ .. ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*'
200 \ .. 'UserFunc().*'
201 \ .. ' UCALL UserFunc(argc 0).*'
202 \ .. 'UserFuncWithArg("foo").*'
203 \ .. ' PUSHS "foo".*'
204 \ .. ' UCALL UserFuncWithArg(argc 1).*'
205 \ .. 'let FuncRef = function("UserFunc").*'
206 \ .. 'FuncRef().*'
207 \ .. ' LOAD $\d.*'
208 \ .. ' PCALL (argc 0).*'
209 \ .. 'let FuncRefWithArg = function("UserFuncWithArg").*'
210 \ .. 'FuncRefWithArg("bar").*'
211 \ .. ' PUSHS "bar".*'
212 \ .. ' LOAD $\d.*'
213 \ .. ' PCALL (argc 1).*'
214 \ .. 'return "yes".*'
215 \ .. ' PUSHS "yes".*'
216 \ .. ' RETURN.*'
217 \, res)
218enddef
219
Bram Moolenaar158906c2020-02-06 20:39:45 +0100220def HasEval()
221 if has("eval")
222 echo "yes"
223 else
224 echo "no"
225 endif
226enddef
227
228def HasNothing()
229 if has("nothing")
230 echo "yes"
231 else
232 echo "no"
233 endif
234enddef
235
236def HasSomething()
237 if has("nothing")
238 echo "nothing"
239 elseif has("something")
240 echo "something"
241 elseif has("eval")
242 echo "eval"
243 elseif has("less")
244 echo "less"
245 endif
246enddef
247
248def Test_compile_const_expr()
249 assert_equal("\nyes", execute('call HasEval()'))
250 let instr = execute('disassemble HasEval')
251 assert_match('HasEval.*'
252 \ .. 'if has("eval").*'
253 \ .. ' PUSHS "yes".*'
254 \, instr)
255 assert_notmatch('JUMP', instr)
256
257 assert_equal("\nno", execute('call HasNothing()'))
258 instr = execute('disassemble HasNothing')
259 assert_match('HasNothing.*'
260 \ .. 'if has("nothing").*'
261 \ .. 'else.*'
262 \ .. ' PUSHS "no".*'
263 \, instr)
264 assert_notmatch('PUSHS "yes"', instr)
265 assert_notmatch('JUMP', instr)
266
267 assert_equal("\neval", execute('call HasSomething()'))
268 instr = execute('disassemble HasSomething')
269 assert_match('HasSomething.*'
270 \ .. 'if has("nothing").*'
271 \ .. 'elseif has("something").*'
272 \ .. 'elseif has("eval").*'
273 \ .. ' PUSHS "eval".*'
274 \ .. 'elseif has("less").*'
275 \, instr)
276 assert_notmatch('PUSHS "nothing"', instr)
277 assert_notmatch('PUSHS "something"', instr)
278 assert_notmatch('PUSHS "less"', instr)
279 assert_notmatch('JUMP', instr)
280enddef
281
Bram Moolenaar777770f2020-02-06 21:27:08 +0100282def WithLambda(): string
283 let F = {a -> "X" .. a .. "X"}
284 return F("x")
285enddef
286
287def Test_compile_lambda()
288 assert_equal("XxX", WithLambda())
289 let instr = execute('disassemble WithLambda')
290 assert_match('WithLambda.*'
291 \ .. 'let F = {a -> "X" .. a .. "X"}.*'
292 \ .. ' FUNCREF <lambda>\d\+.*'
293 \ .. 'PUSHS "x".*'
294 \ .. ' LOAD $0.*'
295 \ .. ' PCALL (argc 1).*'
296 \ .. ' CHECKTYPE string stack\[-1].*'
297 \, instr)
298enddef
299
300def AndOr(arg): string
301 if arg == 1 && arg != 2 || arg == 4
302 return 'yes'
303 endif
304 return 'no'
305enddef
306
307def Test_compile_and_or()
308 assert_equal("yes", AndOr(1))
309 assert_equal("no", AndOr(2))
310 assert_equal("yes", AndOr(4))
311 let instr = execute('disassemble AndOr')
312 assert_match('AndOr.*'
313 \ .. 'if arg == 1 && arg != 2 || arg == 4.*'
314 \ .. '\d LOAD arg\[-1].*'
315 \ .. '\d PUSHNR 1.*'
316 \ .. '\d COMPAREANY ==.*'
317 \ .. '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*'
318 \ .. '\d LOAD arg\[-1].*'
319 \ .. '\d PUSHNR 2.*'
320 \ .. '\d COMPAREANY !=.*'
321 \ .. '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*'
322 \ .. '\d LOAD arg\[-1].*'
323 \ .. '\d PUSHNR 4.*'
324 \ .. '\d COMPAREANY ==.*'
325 \ .. '\d JUMP_IF_FALSE -> \d\+.*'
326 \, instr)
327enddef
328
Bram Moolenaar04d05222020-02-06 22:06:54 +0100329def ForLoop(): list<number>
330 let res: list<number>
331 for i in range(3)
332 res->add(i)
333 endfor
334 return res
335enddef
336
337def Test_compile_for_loop()
338 assert_equal([0, 1, 2], ForLoop())
339 let instr = execute('disassemble ForLoop')
340 assert_match('ForLoop.*'
341 \ .. 'let res: list<number>.*'
342 \ .. ' NEWLIST size 0.*'
343 \ .. '\d STORE $0.*'
344 \ .. 'for i in range(3).*'
345 \ .. '\d STORE -1 in $1.*'
346 \ .. '\d PUSHNR 3.*'
347 \ .. '\d BCALL range(argc 1).*'
348 \ .. '\d FOR $1 -> \d\+.*'
349 \ .. '\d STORE $2.*'
350 \ .. 'res->add(i).*'
351 \ .. '\d LOAD $0.*'
352 \ .. '\d LOAD $2.*'
353 \ .. '\d BCALL add(argc 2).*'
354 \ .. '\d DROP.*'
355 \ .. 'endfor.*'
356 \ .. '\d JUMP -> \d\+.*'
357 \ .. '\d DROP.*'
358 \, instr)
359enddef
360
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100361let g:number = 42
362
363def Computing()
364 let nr = 3
365 let nrres = nr + 7
366 nrres = nr - 7
367 nrres = nr * 7
368 nrres = nr / 7
369 nrres = nr % 7
370
371 let anyres = g:number + 7
372 anyres = g:number - 7
373 anyres = g:number * 7
374 anyres = g:number / 7
375 anyres = g:number % 7
376
377 if has('float')
378 let fl = 3.0
379 let flres = fl + 7.0
380 flres = fl - 7.0
381 flres = fl * 7.0
382 flres = fl / 7.0
383 endif
384enddef
385
386def Test_computing()
387 let instr = execute('disassemble Computing')
388 assert_match('Computing.*'
389 \ .. 'let nr = 3.*'
390 \ .. '\d STORE 3 in $0.*'
391 \ .. 'let nrres = nr + 7.*'
392 \ .. '\d LOAD $0.*'
393 \ .. '\d PUSHNR 7.*'
394 \ .. '\d OPNR +.*'
395 \ .. '\d STORE $1.*'
396 \ .. 'nrres = nr - 7.*'
397 \ .. '\d OPNR -.*'
398 \ .. 'nrres = nr \* 7.*'
399 \ .. '\d OPNR \*.*'
400 \ .. 'nrres = nr / 7.*'
401 \ .. '\d OPNR /.*'
402 \ .. 'nrres = nr % 7.*'
403 \ .. '\d OPNR %.*'
404 \ .. 'let anyres = g:number + 7.*'
405 \ .. '\d LOADG g:number.*'
406 \ .. '\d PUSHNR 7.*'
407 \ .. '\d OPANY +.*'
408 \ .. '\d STORE $2.*'
409 \ .. 'anyres = g:number - 7.*'
410 \ .. '\d OPANY -.*'
411 \ .. 'anyres = g:number \* 7.*'
412 \ .. '\d OPANY \*.*'
413 \ .. 'anyres = g:number / 7.*'
414 \ .. '\d OPANY /.*'
415 \ .. 'anyres = g:number % 7.*'
416 \ .. '\d OPANY %.*'
417 \, instr)
418 if has('float')
419 assert_match('Computing.*'
420 \ .. 'let fl = 3.0.*'
421 \ .. '\d PUSHF 3.0.*'
422 \ .. '\d STORE $3.*'
423 \ .. 'let flres = fl + 7.0.*'
424 \ .. '\d LOAD $3.*'
425 \ .. '\d PUSHF 7.0.*'
426 \ .. '\d OPFLOAT +.*'
427 \ .. '\d STORE $4.*'
428 \ .. 'flres = fl - 7.0.*'
429 \ .. '\d OPFLOAT -.*'
430 \ .. 'flres = fl \* 7.0.*'
431 \ .. '\d OPFLOAT \*.*'
432 \ .. 'flres = fl / 7.0.*'
433 \ .. '\d OPFLOAT /.*'
434 \, instr)
435 endif
436enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100437
438" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker