blob: 9196184a6fca9683793e73f4c35a0e1a8e7dd764 [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
Bram Moolenaarf2460a32020-02-07 22:09:54 +010023def Test_disassemble_load()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010024 assert_fails('disass NoFunc', 'E1061:')
25 assert_fails('disass NotCompiled', 'E1062:')
Bram Moolenaar21456cd2020-02-13 21:29:32 +010026 assert_fails('disass', 'E471:')
27 assert_fails('disass [', 'E475:')
28 assert_fails('disass 234', 'E475:')
29 assert_fails('disass <XX>foo', 'E475:')
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010030
31 let res = execute('disass s:ScriptFuncLoad')
32 assert_match('<SNR>\d*_ScriptFuncLoad.*'
33 \ .. 'buffers.*'
34 \ .. ' EXEC \+buffers.*'
35 \ .. ' LOAD arg\[-1\].*'
36 \ .. ' LOAD $0.*'
37 \ .. ' LOADV v:version.*'
38 \ .. ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*'
39 \ .. ' LOADG g:globalvar.*'
40 \ .. ' LOADENV $ENVVAR.*'
41 \ .. ' LOADREG @z.*'
42 \, res)
43enddef
44
45def s:ScriptFuncPush()
46 let localbool = true
47 let localspec = v:none
48 let localblob = 0z1234
49 if has('float')
50 let localfloat = 1.234
51 endif
52enddef
53
Bram Moolenaarf2460a32020-02-07 22:09:54 +010054def Test_disassemble_push()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010055 let res = execute('disass s:ScriptFuncPush')
56 assert_match('<SNR>\d*_ScriptFuncPush.*'
57 \ .. 'localbool = true.*'
58 \ .. ' PUSH v:true.*'
59 \ .. 'localspec = v:none.*'
60 \ .. ' PUSH v:none.*'
61 \ .. 'localblob = 0z1234.*'
62 \ .. ' PUSHBLOB 0z1234.*'
63 \, res)
64 if has('float')
65 assert_match('<SNR>\d*_ScriptFuncPush.*'
66 \ .. 'localfloat = 1.234.*'
67 \ .. ' PUSHF 1.234.*'
68 \, res)
69 endif
70enddef
71
72def s:ScriptFuncStore()
73 let localnr = 1
74 localnr = 2
75 let localstr = 'abc'
76 localstr = 'xyz'
77 v:char = 'abc'
78 s:scriptvar = 'sv'
79 g:globalvar = 'gv'
80 &tabstop = 8
81 $ENVVAR = 'ev'
82 @z = 'rv'
83enddef
84
Bram Moolenaarf2460a32020-02-07 22:09:54 +010085def Test_disassemble_store()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010086 let res = execute('disass s:ScriptFuncStore')
87 assert_match('<SNR>\d*_ScriptFuncStore.*'
88 \ .. 'localnr = 2.*'
89 \ .. ' STORE 2 in $0.*'
90 \ .. 'localstr = ''xyz''.*'
91 \ .. ' STORE $1.*'
92 \ .. 'v:char = ''abc''.*'
93 \ .. 'STOREV v:char.*'
94 \ .. 's:scriptvar = ''sv''.*'
95 \ .. ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*'
96 \ .. 'g:globalvar = ''gv''.*'
97 \ .. ' STOREG g:globalvar.*'
98 \ .. '&tabstop = 8.*'
99 \ .. ' STOREOPT &tabstop.*'
100 \ .. '$ENVVAR = ''ev''.*'
101 \ .. ' STOREENV $ENVVAR.*'
102 \ .. '@z = ''rv''.*'
103 \ .. ' STOREREG @z.*'
104 \, res)
105enddef
106
107def s:ScriptFuncTry()
108 try
109 echo 'yes'
110 catch /fail/
111 echo 'no'
112 finally
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100113 throw 'end'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100114 endtry
115enddef
116
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100117def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100118 let res = execute('disass s:ScriptFuncTry')
119 assert_match('<SNR>\d*_ScriptFuncTry.*'
120 \ .. 'try.*'
121 \ .. 'TRY catch -> \d\+, finally -> \d\+.*'
122 \ .. 'catch /fail/.*'
123 \ .. ' JUMP -> \d\+.*'
124 \ .. ' PUSH v:exception.*'
125 \ .. ' PUSHS "fail".*'
126 \ .. ' COMPARESTRING =\~.*'
127 \ .. ' JUMP_IF_FALSE -> \d\+.*'
128 \ .. ' CATCH.*'
129 \ .. 'finally.*'
130 \ .. ' PUSHS "end".*'
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100131 \ .. ' THROW.*'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100132 \ .. 'endtry.*'
133 \ .. ' ENDTRY.*'
134 \, res)
135enddef
136
137def s:ScriptFuncNew()
138 let ll = [1, "two", 333]
139 let dd = #{one: 1, two: "val"}
140enddef
141
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100142def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100143 let res = execute('disass s:ScriptFuncNew')
144 assert_match('<SNR>\d*_ScriptFuncNew.*'
145 \ .. 'let ll = \[1, "two", 333].*'
146 \ .. 'PUSHNR 1.*'
147 \ .. 'PUSHS "two".*'
148 \ .. 'PUSHNR 333.*'
149 \ .. 'NEWLIST size 3.*'
150 \ .. 'let dd = #{one: 1, two: "val"}.*'
151 \ .. 'PUSHS "one".*'
152 \ .. 'PUSHNR 1.*'
153 \ .. 'PUSHS "two".*'
154 \ .. 'PUSHS "val".*'
155 \ .. 'NEWDICT size 2.*'
156 \, res)
157enddef
158
159def FuncWithArg(arg)
160 echo arg
161enddef
162
163func UserFunc()
164 echo 'nothing'
165endfunc
166
167func UserFuncWithArg(arg)
168 echo a:arg
169endfunc
170
171def s:ScriptFuncCall(): string
172 changenr()
173 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100174 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100175 FuncWithArg(343)
176 ScriptFuncNew()
177 s:ScriptFuncNew()
178 UserFunc()
179 UserFuncWithArg("foo")
180 let FuncRef = function("UserFunc")
181 FuncRef()
182 let FuncRefWithArg = function("UserFuncWithArg")
183 FuncRefWithArg("bar")
184 return "yes"
185enddef
186
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100187def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100188 let res = execute('disass s:ScriptFuncCall')
189 assert_match('<SNR>\d\+_ScriptFuncCall.*'
190 \ .. 'changenr().*'
191 \ .. ' BCALL changenr(argc 0).*'
192 \ .. 'char2nr("abc").*'
193 \ .. ' PUSHS "abc".*'
194 \ .. ' BCALL char2nr(argc 1).*'
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100195 \ .. 'Test_disassemble_new().*'
196 \ .. ' DCALL Test_disassemble_new(argc 0).*'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100197 \ .. 'FuncWithArg(343).*'
198 \ .. ' PUSHNR 343.*'
199 \ .. ' DCALL FuncWithArg(argc 1).*'
200 \ .. 'ScriptFuncNew().*'
201 \ .. ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*'
202 \ .. 's:ScriptFuncNew().*'
203 \ .. ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*'
204 \ .. 'UserFunc().*'
205 \ .. ' UCALL UserFunc(argc 0).*'
206 \ .. 'UserFuncWithArg("foo").*'
207 \ .. ' PUSHS "foo".*'
208 \ .. ' UCALL UserFuncWithArg(argc 1).*'
209 \ .. 'let FuncRef = function("UserFunc").*'
210 \ .. 'FuncRef().*'
211 \ .. ' LOAD $\d.*'
212 \ .. ' PCALL (argc 0).*'
213 \ .. 'let FuncRefWithArg = function("UserFuncWithArg").*'
214 \ .. 'FuncRefWithArg("bar").*'
215 \ .. ' PUSHS "bar".*'
216 \ .. ' LOAD $\d.*'
217 \ .. ' PCALL (argc 1).*'
218 \ .. 'return "yes".*'
219 \ .. ' PUSHS "yes".*'
220 \ .. ' RETURN.*'
221 \, res)
222enddef
223
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100224
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100225def FuncWithForwardCall(): string
226 return DefinedLater("yes")
227enddef
228
229def DefinedLater(arg: string): string
230 return arg
231enddef
232
233def Test_disassemble_update_instr()
234 let res = execute('disass FuncWithForwardCall')
235 assert_match('FuncWithForwardCall.*'
236 \ .. 'return DefinedLater("yes").*'
237 \ .. '\d PUSHS "yes".*'
238 \ .. '\d UCALL DefinedLater(argc 1).*'
239 \ .. '\d CHECKTYPE string stack\[-1].*'
240 \ .. '\d RETURN.*'
241 \, res)
242
243 " Calling the function will change UCALL into the faster DCALL
244 assert_equal('yes', FuncWithForwardCall())
245
246 res = execute('disass FuncWithForwardCall')
247 assert_match('FuncWithForwardCall.*'
248 \ .. 'return DefinedLater("yes").*'
249 \ .. '\d PUSHS "yes".*'
250 \ .. '\d DCALL DefinedLater(argc 1).*'
251 \ .. '\d CHECKTYPE string stack\[-1].*'
252 \ .. '\d RETURN.*'
253 \, res)
254enddef
255
256
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100257def FuncWithDefault(arg: string = 'default'): string
258 return arg
259enddef
260
261def Test_disassemble_call_default()
262 let res = execute('disass FuncWithDefault')
263 assert_match('FuncWithDefault.*'
264 \ .. '\d PUSHS "default".*'
265 \ .. '\d STORE arg\[-1].*'
266 \ .. 'return arg.*'
267 \ .. '\d LOAD arg\[-1].*'
268 \ .. '\d RETURN.*'
269 \, res)
270enddef
271
272
Bram Moolenaar158906c2020-02-06 20:39:45 +0100273def HasEval()
274 if has("eval")
275 echo "yes"
276 else
277 echo "no"
278 endif
279enddef
280
281def HasNothing()
282 if has("nothing")
283 echo "yes"
284 else
285 echo "no"
286 endif
287enddef
288
289def HasSomething()
290 if has("nothing")
291 echo "nothing"
292 elseif has("something")
293 echo "something"
294 elseif has("eval")
295 echo "eval"
296 elseif has("less")
297 echo "less"
298 endif
299enddef
300
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100301def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100302 assert_equal("\nyes", execute('call HasEval()'))
303 let instr = execute('disassemble HasEval')
304 assert_match('HasEval.*'
305 \ .. 'if has("eval").*'
306 \ .. ' PUSHS "yes".*'
307 \, instr)
308 assert_notmatch('JUMP', instr)
309
310 assert_equal("\nno", execute('call HasNothing()'))
311 instr = execute('disassemble HasNothing')
312 assert_match('HasNothing.*'
313 \ .. 'if has("nothing").*'
314 \ .. 'else.*'
315 \ .. ' PUSHS "no".*'
316 \, instr)
317 assert_notmatch('PUSHS "yes"', instr)
318 assert_notmatch('JUMP', instr)
319
320 assert_equal("\neval", execute('call HasSomething()'))
321 instr = execute('disassemble HasSomething')
322 assert_match('HasSomething.*'
323 \ .. 'if has("nothing").*'
324 \ .. 'elseif has("something").*'
325 \ .. 'elseif has("eval").*'
326 \ .. ' PUSHS "eval".*'
327 \ .. 'elseif has("less").*'
328 \, instr)
329 assert_notmatch('PUSHS "nothing"', instr)
330 assert_notmatch('PUSHS "something"', instr)
331 assert_notmatch('PUSHS "less"', instr)
332 assert_notmatch('JUMP', instr)
333enddef
334
Bram Moolenaar777770f2020-02-06 21:27:08 +0100335def WithLambda(): string
336 let F = {a -> "X" .. a .. "X"}
337 return F("x")
338enddef
339
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100340def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100341 assert_equal("XxX", WithLambda())
342 let instr = execute('disassemble WithLambda')
343 assert_match('WithLambda.*'
344 \ .. 'let F = {a -> "X" .. a .. "X"}.*'
345 \ .. ' FUNCREF <lambda>\d\+.*'
346 \ .. 'PUSHS "x".*'
347 \ .. ' LOAD $0.*'
348 \ .. ' PCALL (argc 1).*'
349 \ .. ' CHECKTYPE string stack\[-1].*'
350 \, instr)
351enddef
352
353def AndOr(arg): string
354 if arg == 1 && arg != 2 || arg == 4
355 return 'yes'
356 endif
357 return 'no'
358enddef
359
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100360def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100361 assert_equal("yes", AndOr(1))
362 assert_equal("no", AndOr(2))
363 assert_equal("yes", AndOr(4))
364 let instr = execute('disassemble AndOr')
365 assert_match('AndOr.*'
366 \ .. 'if arg == 1 && arg != 2 || arg == 4.*'
367 \ .. '\d LOAD arg\[-1].*'
368 \ .. '\d PUSHNR 1.*'
369 \ .. '\d COMPAREANY ==.*'
370 \ .. '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*'
371 \ .. '\d LOAD arg\[-1].*'
372 \ .. '\d PUSHNR 2.*'
373 \ .. '\d COMPAREANY !=.*'
374 \ .. '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*'
375 \ .. '\d LOAD arg\[-1].*'
376 \ .. '\d PUSHNR 4.*'
377 \ .. '\d COMPAREANY ==.*'
378 \ .. '\d JUMP_IF_FALSE -> \d\+.*'
379 \, instr)
380enddef
381
Bram Moolenaar04d05222020-02-06 22:06:54 +0100382def ForLoop(): list<number>
383 let res: list<number>
384 for i in range(3)
385 res->add(i)
386 endfor
387 return res
388enddef
389
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100390def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100391 assert_equal([0, 1, 2], ForLoop())
392 let instr = execute('disassemble ForLoop')
393 assert_match('ForLoop.*'
394 \ .. 'let res: list<number>.*'
395 \ .. ' NEWLIST size 0.*'
396 \ .. '\d STORE $0.*'
397 \ .. 'for i in range(3).*'
398 \ .. '\d STORE -1 in $1.*'
399 \ .. '\d PUSHNR 3.*'
400 \ .. '\d BCALL range(argc 1).*'
401 \ .. '\d FOR $1 -> \d\+.*'
402 \ .. '\d STORE $2.*'
403 \ .. 'res->add(i).*'
404 \ .. '\d LOAD $0.*'
405 \ .. '\d LOAD $2.*'
406 \ .. '\d BCALL add(argc 2).*'
407 \ .. '\d DROP.*'
408 \ .. 'endfor.*'
409 \ .. '\d JUMP -> \d\+.*'
410 \ .. '\d DROP.*'
411 \, instr)
412enddef
413
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100414let g:number = 42
415
416def Computing()
417 let nr = 3
418 let nrres = nr + 7
419 nrres = nr - 7
420 nrres = nr * 7
421 nrres = nr / 7
422 nrres = nr % 7
423
424 let anyres = g:number + 7
425 anyres = g:number - 7
426 anyres = g:number * 7
427 anyres = g:number / 7
428 anyres = g:number % 7
429
430 if has('float')
431 let fl = 3.0
432 let flres = fl + 7.0
433 flres = fl - 7.0
434 flres = fl * 7.0
435 flres = fl / 7.0
436 endif
437enddef
438
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100439def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100440 let instr = execute('disassemble Computing')
441 assert_match('Computing.*'
442 \ .. 'let nr = 3.*'
443 \ .. '\d STORE 3 in $0.*'
444 \ .. 'let nrres = nr + 7.*'
445 \ .. '\d LOAD $0.*'
446 \ .. '\d PUSHNR 7.*'
447 \ .. '\d OPNR +.*'
448 \ .. '\d STORE $1.*'
449 \ .. 'nrres = nr - 7.*'
450 \ .. '\d OPNR -.*'
451 \ .. 'nrres = nr \* 7.*'
452 \ .. '\d OPNR \*.*'
453 \ .. 'nrres = nr / 7.*'
454 \ .. '\d OPNR /.*'
455 \ .. 'nrres = nr % 7.*'
456 \ .. '\d OPNR %.*'
457 \ .. 'let anyres = g:number + 7.*'
458 \ .. '\d LOADG g:number.*'
459 \ .. '\d PUSHNR 7.*'
460 \ .. '\d OPANY +.*'
461 \ .. '\d STORE $2.*'
462 \ .. 'anyres = g:number - 7.*'
463 \ .. '\d OPANY -.*'
464 \ .. 'anyres = g:number \* 7.*'
465 \ .. '\d OPANY \*.*'
466 \ .. 'anyres = g:number / 7.*'
467 \ .. '\d OPANY /.*'
468 \ .. 'anyres = g:number % 7.*'
469 \ .. '\d OPANY %.*'
470 \, instr)
471 if has('float')
472 assert_match('Computing.*'
473 \ .. 'let fl = 3.0.*'
474 \ .. '\d PUSHF 3.0.*'
475 \ .. '\d STORE $3.*'
476 \ .. 'let flres = fl + 7.0.*'
477 \ .. '\d LOAD $3.*'
478 \ .. '\d PUSHF 7.0.*'
479 \ .. '\d OPFLOAT +.*'
480 \ .. '\d STORE $4.*'
481 \ .. 'flres = fl - 7.0.*'
482 \ .. '\d OPFLOAT -.*'
483 \ .. 'flres = fl \* 7.0.*'
484 \ .. '\d OPFLOAT \*.*'
485 \ .. 'flres = fl / 7.0.*'
486 \ .. '\d OPFLOAT /.*'
487 \, instr)
488 endif
489enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100490
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100491def AddListBlob()
492 let reslist = [1, 2] + [3, 4]
493 let resblob = 0z1122 + 0z3344
494enddef
495
496def Test_disassemble_add_list_blob()
497 let instr = execute('disassemble AddListBlob')
498 assert_match('AddListBlob.*'
499 \ .. 'let reslist = \[1, 2] + \[3, 4].*'
500 \ .. '\d PUSHNR 1.*'
501 \ .. '\d PUSHNR 2.*'
502 \ .. '\d NEWLIST size 2.*'
503 \ .. '\d PUSHNR 3.*'
504 \ .. '\d PUSHNR 4.*'
505 \ .. '\d NEWLIST size 2.*'
506 \ .. '\d ADDLIST.*'
507 \ .. '\d STORE $.*.*'
508 \ .. 'let resblob = 0z1122 + 0z3344.*'
509 \ .. '\d PUSHBLOB 0z1122.*'
510 \ .. '\d PUSHBLOB 0z3344.*'
511 \ .. '\d ADDBLOB.*'
512 \ .. '\d STORE $.*'
513 \, instr)
514enddef
515
516let g:aa = 'aa'
517def ConcatString(): string
518 let res = g:aa .. "bb"
519 return res
520enddef
521
522def Test_disassemble_concat()
523 let instr = execute('disassemble ConcatString')
524 assert_match('ConcatString.*'
525 \ .. 'let res = g:aa .. "bb".*'
526 \ .. '\d LOADG g:aa.*'
527 \ .. '\d PUSHS "bb".*'
528 \ .. '\d 2STRING stack\[-2].*'
529 \ .. '\d CONCAT.*'
530 \ .. '\d STORE $.*'
531 \, instr)
532 assert_equal('aabb', ConcatString())
533enddef
534
535def ListIndex(): number
536 let l = [1, 2, 3]
537 let res = l[1]
538 return res
539enddef
540
541def Test_disassemble_list_index()
542 let instr = execute('disassemble ListIndex')
543 assert_match('ListIndex.*'
544 \ .. 'let l = \[1, 2, 3].*'
545 \ .. '\d PUSHNR 1.*'
546 \ .. '\d PUSHNR 2.*'
547 \ .. '\d PUSHNR 3.*'
548 \ .. '\d NEWLIST size 3.*'
549 \ .. '\d STORE $0.*'
550 \ .. 'let res = l\[1].*'
551 \ .. '\d LOAD $0.*'
552 \ .. '\d PUSHNR 1.*'
553 \ .. '\d INDEX.*'
554 \ .. '\d STORE $1.*'
555 \, instr)
556 assert_equal(2, ListIndex())
557enddef
558
559def DictMember(): number
560 let d = #{item: 1}
561 let res = d.item
562 return res
563enddef
564
565def Test_disassemble_dict_member()
566 let instr = execute('disassemble DictMember')
567 assert_match('DictMember.*'
568 \ .. 'let d = #{item: 1}.*'
569 \ .. '\d PUSHS "item".*'
570 \ .. '\d PUSHNR 1.*'
571 \ .. '\d NEWDICT size 1.*'
572 \ .. '\d STORE $0.*'
573 \ .. 'let res = d.item.*'
574 \ .. '\d LOAD $0.*'
575 \ .. '\d MEMBER item.*'
576 \ .. '\d STORE $1.*'
577 \, instr)
578 call assert_equal(1, DictMember())
579enddef
580
581def NegateNumber(): number
582 let nr = 9
583 let plus = +nr
584 let res = -nr
585 return res
586enddef
587
588def Test_disassemble_negate_number()
589 let instr = execute('disassemble NegateNumber')
590 assert_match('NegateNumber.*'
591 \ .. 'let nr = 9.*'
592 \ .. '\d STORE 9 in $0.*'
593 \ .. 'let plus = +nr.*'
594 \ .. '\d LOAD $0.*'
595 \ .. '\d CHECKNR.*'
596 \ .. '\d STORE $1.*'
597 \ .. 'let res = -nr.*'
598 \ .. '\d LOAD $0.*'
599 \ .. '\d NEGATENR.*'
600 \ .. '\d STORE $2.*'
601 \, instr)
602 call assert_equal(-9, NegateNumber())
603enddef
604
605def InvertBool(): bool
606 let flag = true
607 let invert = !flag
608 let res = !!flag
609 return res
610enddef
611
612def Test_disassemble_invert_bool()
613 let instr = execute('disassemble InvertBool')
614 assert_match('InvertBool.*'
615 \ .. 'let flag = true.*'
616 \ .. '\d PUSH v:true.*'
617 \ .. '\d STORE $0.*'
618 \ .. 'let invert = !flag.*'
619 \ .. '\d LOAD $0.*'
620 \ .. '\d INVERT (!val).*'
621 \ .. '\d STORE $1.*'
622 \ .. 'let res = !!flag.*'
623 \ .. '\d LOAD $0.*'
624 \ .. '\d 2BOOL (!!val).*'
625 \ .. '\d STORE $2.*'
626 \, instr)
627 call assert_equal(true, InvertBool())
628enddef
629
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100630def Test_disassemble_compare()
631 " TODO: COMPAREFUNC
632 let cases = [
633 \ ['true == false', 'COMPAREBOOL =='],
634 \ ['true != false', 'COMPAREBOOL !='],
635 \ ['v:none == v:null', 'COMPARESPECIAL =='],
636 \ ['v:none != v:null', 'COMPARESPECIAL !='],
637 \
638 \ ['111 == 222', 'COMPARENR =='],
639 \ ['111 != 222', 'COMPARENR !='],
640 \ ['111 > 222', 'COMPARENR >'],
641 \ ['111 < 222', 'COMPARENR <'],
642 \ ['111 >= 222', 'COMPARENR >='],
643 \ ['111 <= 222', 'COMPARENR <='],
644 \ ['111 =~ 222', 'COMPARENR =\~'],
645 \ ['111 !~ 222', 'COMPARENR !\~'],
646 \
647 \ ['"xx" == "yy"', 'COMPARESTRING =='],
648 \ ['"xx" != "yy"', 'COMPARESTRING !='],
649 \ ['"xx" > "yy"', 'COMPARESTRING >'],
650 \ ['"xx" < "yy"', 'COMPARESTRING <'],
651 \ ['"xx" >= "yy"', 'COMPARESTRING >='],
652 \ ['"xx" <= "yy"', 'COMPARESTRING <='],
653 \ ['"xx" =~ "yy"', 'COMPARESTRING =\~'],
654 \ ['"xx" !~ "yy"', 'COMPARESTRING !\~'],
655 \ ['"xx" is "yy"', 'COMPARESTRING is'],
656 \ ['"xx" isnot "yy"', 'COMPARESTRING isnot'],
657 \
658 \ ['0z11 == 0z22', 'COMPAREBLOB =='],
659 \ ['0z11 != 0z22', 'COMPAREBLOB !='],
660 \ ['0z11 is 0z22', 'COMPAREBLOB is'],
661 \ ['0z11 isnot 0z22', 'COMPAREBLOB isnot'],
662 \
663 \ ['[1,2] == [3,4]', 'COMPARELIST =='],
664 \ ['[1,2] != [3,4]', 'COMPARELIST !='],
665 \ ['[1,2] is [3,4]', 'COMPARELIST is'],
666 \ ['[1,2] isnot [3,4]', 'COMPARELIST isnot'],
667 \
668 \ ['#{a:1} == #{x:2}', 'COMPAREDICT =='],
669 \ ['#{a:1} != #{x:2}', 'COMPAREDICT !='],
670 \ ['#{a:1} is #{x:2}', 'COMPAREDICT is'],
671 \ ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'],
672 \
673 \ ['{->33} == {->44}', 'COMPAREPARTIAL =='],
674 \ ['{->33} != {->44}', 'COMPAREPARTIAL !='],
675 \ ['{->33} is {->44}', 'COMPAREPARTIAL is'],
676 \ ['{->33} isnot {->44}', 'COMPAREPARTIAL isnot'],
677 \
678 \ ['77 == g:xx', 'COMPAREANY =='],
679 \ ['77 != g:xx', 'COMPAREANY !='],
680 \ ['77 > g:xx', 'COMPAREANY >'],
681 \ ['77 < g:xx', 'COMPAREANY <'],
682 \ ['77 >= g:xx', 'COMPAREANY >='],
683 \ ['77 <= g:xx', 'COMPAREANY <='],
684 \ ['77 =~ g:xx', 'COMPAREANY =\~'],
685 \ ['77 !~ g:xx', 'COMPAREANY !\~'],
686 \ ['77 is g:xx', 'COMPAREANY is'],
687 \ ['77 isnot g:xx', 'COMPAREANY isnot'],
688 \ ]
689 if has('float')
690 cases->extend([
691 \ ['1.1 == 2.2', 'COMPAREFLOAT =='],
692 \ ['1.1 != 2.2', 'COMPAREFLOAT !='],
693 \ ['1.1 > 2.2', 'COMPAREFLOAT >'],
694 \ ['1.1 < 2.2', 'COMPAREFLOAT <'],
695 \ ['1.1 >= 2.2', 'COMPAREFLOAT >='],
696 \ ['1.1 <= 2.2', 'COMPAREFLOAT <='],
697 \ ['1.1 =~ 2.2', 'COMPAREFLOAT =\~'],
698 \ ['1.1 !~ 2.2', 'COMPAREFLOAT !\~'],
699 \ ])
700 endif
701
702 let nr = 1
703 for case in cases
704 writefile(['def TestCase' .. nr .. '()',
705 \ ' if ' .. case[0],
706 \ ' echo 42'
707 \ ' endif',
708 \ 'enddef'], 'Xdisassemble')
709 source Xdisassemble
710 let instr = execute('disassemble TestCase' .. nr)
711 assert_match('TestCase' .. nr .. '.*'
712 \ .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*'
713 \ .. '\d \(PUSH\|FUNCREF\).*'
714 \ .. '\d \(PUSH\|FUNCREF\|LOADG\).*'
715 \ .. '\d ' .. case[1] .. '.*'
716 \ .. '\d JUMP_IF_FALSE -> \d\+.*'
717 \, instr)
718
719 nr += 1
720 endfor
721
722 " delete('Xdisassemble')
723enddef
724
Bram Moolenaarad39c092020-02-26 18:23:43 +0100725def s:Execute()
726 execute 'help vim9.txt'
727 let cmd = 'help vim9.txt'
728 execute cmd
729 let tag = 'vim9.txt'
730 execute 'help ' .. tag
731enddef
732
733def Test_disassemble_execute()
734 let res = execute('disass s:Execute')
735 assert_match('\<SNR>\d*_Execute.*'
736 \ .. "execute 'help vim9.txt'.*"
737 \ .. '\d PUSHS "help vim9.txt".*'
738 \ .. '\d EXECUTE 1.*'
739 \ .. "let cmd = 'help vim9.txt'.*"
740 \ .. '\d PUSHS "help vim9.txt".*'
741 \ .. '\d STORE $0.*'
742 \ .. 'execute cmd.*'
743 \ .. '\d LOAD $0.*'
744 \ .. '\d EXECUTE 1.*'
745 \ .. "let tag = 'vim9.txt'.*"
746 \ .. '\d PUSHS "vim9.txt".*'
747 \ .. '\d STORE $1.*'
748 \ .. "execute 'help ' .. tag.*"
749 \ .. '\d PUSHS "help ".*'
750 \ .. '\d LOAD $1.*'
751 \ .. '\d CONCAT.*'
752 \ .. '\d EXECUTE 1.*'
753 \ .. '\d PUSHNR 0.*'
754 \ .. '\d RETURN'
755 \, res)
756enddef
757
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100758" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker