1" 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_disassemble_load() 24 assert_fails('disass NoFunc', 'E1061:') 25 assert_fails('disass NotCompiled', 'E1062:') 26 assert_fails('disass', 'E471:') 27 assert_fails('disass [', 'E475:') 28 assert_fails('disass 234', 'E475:') 29 assert_fails('disass <XX>foo', 'E475:') 30 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 54def Test_disassemble_push() 55 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 85def Test_disassemble_store() 86 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 113 throw 'end' 114 endtry 115enddef 116 117def Test_disassemble_try() 118 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".*' 131 \ .. ' THROW.*' 132 \ .. '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 142def Test_disassemble_new() 143 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") 174 Test_disassemble_new() 175 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 187def Test_disassemble_call() 188 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).*' 195 \ .. 'Test_disassemble_new().*' 196 \ .. ' DCALL Test_disassemble_new(argc 0).*' 197 \ .. '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 224 225def FuncWithDefault(arg: string = 'default'): string 226 return arg 227enddef 228 229def Test_disassemble_call_default() 230 let res = execute('disass FuncWithDefault') 231 assert_match('FuncWithDefault.*' 232 \ .. '\d PUSHS "default".*' 233 \ .. '\d STORE arg\[-1].*' 234 \ .. 'return arg.*' 235 \ .. '\d LOAD arg\[-1].*' 236 \ .. '\d RETURN.*' 237 \, res) 238enddef 239 240 241def HasEval() 242 if has("eval") 243 echo "yes" 244 else 245 echo "no" 246 endif 247enddef 248 249def HasNothing() 250 if has("nothing") 251 echo "yes" 252 else 253 echo "no" 254 endif 255enddef 256 257def HasSomething() 258 if has("nothing") 259 echo "nothing" 260 elseif has("something") 261 echo "something" 262 elseif has("eval") 263 echo "eval" 264 elseif has("less") 265 echo "less" 266 endif 267enddef 268 269def Test_disassemble_const_expr() 270 assert_equal("\nyes", execute('call HasEval()')) 271 let instr = execute('disassemble HasEval') 272 assert_match('HasEval.*' 273 \ .. 'if has("eval").*' 274 \ .. ' PUSHS "yes".*' 275 \, instr) 276 assert_notmatch('JUMP', instr) 277 278 assert_equal("\nno", execute('call HasNothing()')) 279 instr = execute('disassemble HasNothing') 280 assert_match('HasNothing.*' 281 \ .. 'if has("nothing").*' 282 \ .. 'else.*' 283 \ .. ' PUSHS "no".*' 284 \, instr) 285 assert_notmatch('PUSHS "yes"', instr) 286 assert_notmatch('JUMP', instr) 287 288 assert_equal("\neval", execute('call HasSomething()')) 289 instr = execute('disassemble HasSomething') 290 assert_match('HasSomething.*' 291 \ .. 'if has("nothing").*' 292 \ .. 'elseif has("something").*' 293 \ .. 'elseif has("eval").*' 294 \ .. ' PUSHS "eval".*' 295 \ .. 'elseif has("less").*' 296 \, instr) 297 assert_notmatch('PUSHS "nothing"', instr) 298 assert_notmatch('PUSHS "something"', instr) 299 assert_notmatch('PUSHS "less"', instr) 300 assert_notmatch('JUMP', instr) 301enddef 302 303def WithLambda(): string 304 let F = {a -> "X" .. a .. "X"} 305 return F("x") 306enddef 307 308def Test_disassemble_lambda() 309 assert_equal("XxX", WithLambda()) 310 let instr = execute('disassemble WithLambda') 311 assert_match('WithLambda.*' 312 \ .. 'let F = {a -> "X" .. a .. "X"}.*' 313 \ .. ' FUNCREF <lambda>\d\+.*' 314 \ .. 'PUSHS "x".*' 315 \ .. ' LOAD $0.*' 316 \ .. ' PCALL (argc 1).*' 317 \ .. ' CHECKTYPE string stack\[-1].*' 318 \, instr) 319enddef 320 321def AndOr(arg): string 322 if arg == 1 && arg != 2 || arg == 4 323 return 'yes' 324 endif 325 return 'no' 326enddef 327 328def Test_disassemble_and_or() 329 assert_equal("yes", AndOr(1)) 330 assert_equal("no", AndOr(2)) 331 assert_equal("yes", AndOr(4)) 332 let instr = execute('disassemble AndOr') 333 assert_match('AndOr.*' 334 \ .. 'if arg == 1 && arg != 2 || arg == 4.*' 335 \ .. '\d LOAD arg\[-1].*' 336 \ .. '\d PUSHNR 1.*' 337 \ .. '\d COMPAREANY ==.*' 338 \ .. '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*' 339 \ .. '\d LOAD arg\[-1].*' 340 \ .. '\d PUSHNR 2.*' 341 \ .. '\d COMPAREANY !=.*' 342 \ .. '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*' 343 \ .. '\d LOAD arg\[-1].*' 344 \ .. '\d PUSHNR 4.*' 345 \ .. '\d COMPAREANY ==.*' 346 \ .. '\d JUMP_IF_FALSE -> \d\+.*' 347 \, instr) 348enddef 349 350def ForLoop(): list<number> 351 let res: list<number> 352 for i in range(3) 353 res->add(i) 354 endfor 355 return res 356enddef 357 358def Test_disassemble_for_loop() 359 assert_equal([0, 1, 2], ForLoop()) 360 let instr = execute('disassemble ForLoop') 361 assert_match('ForLoop.*' 362 \ .. 'let res: list<number>.*' 363 \ .. ' NEWLIST size 0.*' 364 \ .. '\d STORE $0.*' 365 \ .. 'for i in range(3).*' 366 \ .. '\d STORE -1 in $1.*' 367 \ .. '\d PUSHNR 3.*' 368 \ .. '\d BCALL range(argc 1).*' 369 \ .. '\d FOR $1 -> \d\+.*' 370 \ .. '\d STORE $2.*' 371 \ .. 'res->add(i).*' 372 \ .. '\d LOAD $0.*' 373 \ .. '\d LOAD $2.*' 374 \ .. '\d BCALL add(argc 2).*' 375 \ .. '\d DROP.*' 376 \ .. 'endfor.*' 377 \ .. '\d JUMP -> \d\+.*' 378 \ .. '\d DROP.*' 379 \, instr) 380enddef 381 382let g:number = 42 383 384def Computing() 385 let nr = 3 386 let nrres = nr + 7 387 nrres = nr - 7 388 nrres = nr * 7 389 nrres = nr / 7 390 nrres = nr % 7 391 392 let anyres = g:number + 7 393 anyres = g:number - 7 394 anyres = g:number * 7 395 anyres = g:number / 7 396 anyres = g:number % 7 397 398 if has('float') 399 let fl = 3.0 400 let flres = fl + 7.0 401 flres = fl - 7.0 402 flres = fl * 7.0 403 flres = fl / 7.0 404 endif 405enddef 406 407def Test_disassemble_computing() 408 let instr = execute('disassemble Computing') 409 assert_match('Computing.*' 410 \ .. 'let nr = 3.*' 411 \ .. '\d STORE 3 in $0.*' 412 \ .. 'let nrres = nr + 7.*' 413 \ .. '\d LOAD $0.*' 414 \ .. '\d PUSHNR 7.*' 415 \ .. '\d OPNR +.*' 416 \ .. '\d STORE $1.*' 417 \ .. 'nrres = nr - 7.*' 418 \ .. '\d OPNR -.*' 419 \ .. 'nrres = nr \* 7.*' 420 \ .. '\d OPNR \*.*' 421 \ .. 'nrres = nr / 7.*' 422 \ .. '\d OPNR /.*' 423 \ .. 'nrres = nr % 7.*' 424 \ .. '\d OPNR %.*' 425 \ .. 'let anyres = g:number + 7.*' 426 \ .. '\d LOADG g:number.*' 427 \ .. '\d PUSHNR 7.*' 428 \ .. '\d OPANY +.*' 429 \ .. '\d STORE $2.*' 430 \ .. 'anyres = g:number - 7.*' 431 \ .. '\d OPANY -.*' 432 \ .. 'anyres = g:number \* 7.*' 433 \ .. '\d OPANY \*.*' 434 \ .. 'anyres = g:number / 7.*' 435 \ .. '\d OPANY /.*' 436 \ .. 'anyres = g:number % 7.*' 437 \ .. '\d OPANY %.*' 438 \, instr) 439 if has('float') 440 assert_match('Computing.*' 441 \ .. 'let fl = 3.0.*' 442 \ .. '\d PUSHF 3.0.*' 443 \ .. '\d STORE $3.*' 444 \ .. 'let flres = fl + 7.0.*' 445 \ .. '\d LOAD $3.*' 446 \ .. '\d PUSHF 7.0.*' 447 \ .. '\d OPFLOAT +.*' 448 \ .. '\d STORE $4.*' 449 \ .. 'flres = fl - 7.0.*' 450 \ .. '\d OPFLOAT -.*' 451 \ .. 'flres = fl \* 7.0.*' 452 \ .. '\d OPFLOAT \*.*' 453 \ .. 'flres = fl / 7.0.*' 454 \ .. '\d OPFLOAT /.*' 455 \, instr) 456 endif 457enddef 458 459def AddListBlob() 460 let reslist = [1, 2] + [3, 4] 461 let resblob = 0z1122 + 0z3344 462enddef 463 464def Test_disassemble_add_list_blob() 465 let instr = execute('disassemble AddListBlob') 466 assert_match('AddListBlob.*' 467 \ .. 'let reslist = \[1, 2] + \[3, 4].*' 468 \ .. '\d PUSHNR 1.*' 469 \ .. '\d PUSHNR 2.*' 470 \ .. '\d NEWLIST size 2.*' 471 \ .. '\d PUSHNR 3.*' 472 \ .. '\d PUSHNR 4.*' 473 \ .. '\d NEWLIST size 2.*' 474 \ .. '\d ADDLIST.*' 475 \ .. '\d STORE $.*.*' 476 \ .. 'let resblob = 0z1122 + 0z3344.*' 477 \ .. '\d PUSHBLOB 0z1122.*' 478 \ .. '\d PUSHBLOB 0z3344.*' 479 \ .. '\d ADDBLOB.*' 480 \ .. '\d STORE $.*' 481 \, instr) 482enddef 483 484let g:aa = 'aa' 485def ConcatString(): string 486 let res = g:aa .. "bb" 487 return res 488enddef 489 490def Test_disassemble_concat() 491 let instr = execute('disassemble ConcatString') 492 assert_match('ConcatString.*' 493 \ .. 'let res = g:aa .. "bb".*' 494 \ .. '\d LOADG g:aa.*' 495 \ .. '\d PUSHS "bb".*' 496 \ .. '\d 2STRING stack\[-2].*' 497 \ .. '\d CONCAT.*' 498 \ .. '\d STORE $.*' 499 \, instr) 500 assert_equal('aabb', ConcatString()) 501enddef 502 503def ListIndex(): number 504 let l = [1, 2, 3] 505 let res = l[1] 506 return res 507enddef 508 509def Test_disassemble_list_index() 510 let instr = execute('disassemble ListIndex') 511 assert_match('ListIndex.*' 512 \ .. 'let l = \[1, 2, 3].*' 513 \ .. '\d PUSHNR 1.*' 514 \ .. '\d PUSHNR 2.*' 515 \ .. '\d PUSHNR 3.*' 516 \ .. '\d NEWLIST size 3.*' 517 \ .. '\d STORE $0.*' 518 \ .. 'let res = l\[1].*' 519 \ .. '\d LOAD $0.*' 520 \ .. '\d PUSHNR 1.*' 521 \ .. '\d INDEX.*' 522 \ .. '\d STORE $1.*' 523 \, instr) 524 assert_equal(2, ListIndex()) 525enddef 526 527def DictMember(): number 528 let d = #{item: 1} 529 let res = d.item 530 return res 531enddef 532 533def Test_disassemble_dict_member() 534 let instr = execute('disassemble DictMember') 535 assert_match('DictMember.*' 536 \ .. 'let d = #{item: 1}.*' 537 \ .. '\d PUSHS "item".*' 538 \ .. '\d PUSHNR 1.*' 539 \ .. '\d NEWDICT size 1.*' 540 \ .. '\d STORE $0.*' 541 \ .. 'let res = d.item.*' 542 \ .. '\d LOAD $0.*' 543 \ .. '\d MEMBER item.*' 544 \ .. '\d STORE $1.*' 545 \, instr) 546 call assert_equal(1, DictMember()) 547enddef 548 549def NegateNumber(): number 550 let nr = 9 551 let plus = +nr 552 let res = -nr 553 return res 554enddef 555 556def Test_disassemble_negate_number() 557 let instr = execute('disassemble NegateNumber') 558 assert_match('NegateNumber.*' 559 \ .. 'let nr = 9.*' 560 \ .. '\d STORE 9 in $0.*' 561 \ .. 'let plus = +nr.*' 562 \ .. '\d LOAD $0.*' 563 \ .. '\d CHECKNR.*' 564 \ .. '\d STORE $1.*' 565 \ .. 'let res = -nr.*' 566 \ .. '\d LOAD $0.*' 567 \ .. '\d NEGATENR.*' 568 \ .. '\d STORE $2.*' 569 \, instr) 570 call assert_equal(-9, NegateNumber()) 571enddef 572 573def InvertBool(): bool 574 let flag = true 575 let invert = !flag 576 let res = !!flag 577 return res 578enddef 579 580def Test_disassemble_invert_bool() 581 let instr = execute('disassemble InvertBool') 582 assert_match('InvertBool.*' 583 \ .. 'let flag = true.*' 584 \ .. '\d PUSH v:true.*' 585 \ .. '\d STORE $0.*' 586 \ .. 'let invert = !flag.*' 587 \ .. '\d LOAD $0.*' 588 \ .. '\d INVERT (!val).*' 589 \ .. '\d STORE $1.*' 590 \ .. 'let res = !!flag.*' 591 \ .. '\d LOAD $0.*' 592 \ .. '\d 2BOOL (!!val).*' 593 \ .. '\d STORE $2.*' 594 \, instr) 595 call assert_equal(true, InvertBool()) 596enddef 597 598def Test_disassemble_compare() 599 " TODO: COMPAREFUNC 600 let cases = [ 601 \ ['true == false', 'COMPAREBOOL =='], 602 \ ['true != false', 'COMPAREBOOL !='], 603 \ ['v:none == v:null', 'COMPARESPECIAL =='], 604 \ ['v:none != v:null', 'COMPARESPECIAL !='], 605 \ 606 \ ['111 == 222', 'COMPARENR =='], 607 \ ['111 != 222', 'COMPARENR !='], 608 \ ['111 > 222', 'COMPARENR >'], 609 \ ['111 < 222', 'COMPARENR <'], 610 \ ['111 >= 222', 'COMPARENR >='], 611 \ ['111 <= 222', 'COMPARENR <='], 612 \ ['111 =~ 222', 'COMPARENR =\~'], 613 \ ['111 !~ 222', 'COMPARENR !\~'], 614 \ 615 \ ['"xx" == "yy"', 'COMPARESTRING =='], 616 \ ['"xx" != "yy"', 'COMPARESTRING !='], 617 \ ['"xx" > "yy"', 'COMPARESTRING >'], 618 \ ['"xx" < "yy"', 'COMPARESTRING <'], 619 \ ['"xx" >= "yy"', 'COMPARESTRING >='], 620 \ ['"xx" <= "yy"', 'COMPARESTRING <='], 621 \ ['"xx" =~ "yy"', 'COMPARESTRING =\~'], 622 \ ['"xx" !~ "yy"', 'COMPARESTRING !\~'], 623 \ ['"xx" is "yy"', 'COMPARESTRING is'], 624 \ ['"xx" isnot "yy"', 'COMPARESTRING isnot'], 625 \ 626 \ ['0z11 == 0z22', 'COMPAREBLOB =='], 627 \ ['0z11 != 0z22', 'COMPAREBLOB !='], 628 \ ['0z11 is 0z22', 'COMPAREBLOB is'], 629 \ ['0z11 isnot 0z22', 'COMPAREBLOB isnot'], 630 \ 631 \ ['[1,2] == [3,4]', 'COMPARELIST =='], 632 \ ['[1,2] != [3,4]', 'COMPARELIST !='], 633 \ ['[1,2] is [3,4]', 'COMPARELIST is'], 634 \ ['[1,2] isnot [3,4]', 'COMPARELIST isnot'], 635 \ 636 \ ['#{a:1} == #{x:2}', 'COMPAREDICT =='], 637 \ ['#{a:1} != #{x:2}', 'COMPAREDICT !='], 638 \ ['#{a:1} is #{x:2}', 'COMPAREDICT is'], 639 \ ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'], 640 \ 641 \ ['{->33} == {->44}', 'COMPAREPARTIAL =='], 642 \ ['{->33} != {->44}', 'COMPAREPARTIAL !='], 643 \ ['{->33} is {->44}', 'COMPAREPARTIAL is'], 644 \ ['{->33} isnot {->44}', 'COMPAREPARTIAL isnot'], 645 \ 646 \ ['77 == g:xx', 'COMPAREANY =='], 647 \ ['77 != g:xx', 'COMPAREANY !='], 648 \ ['77 > g:xx', 'COMPAREANY >'], 649 \ ['77 < g:xx', 'COMPAREANY <'], 650 \ ['77 >= g:xx', 'COMPAREANY >='], 651 \ ['77 <= g:xx', 'COMPAREANY <='], 652 \ ['77 =~ g:xx', 'COMPAREANY =\~'], 653 \ ['77 !~ g:xx', 'COMPAREANY !\~'], 654 \ ['77 is g:xx', 'COMPAREANY is'], 655 \ ['77 isnot g:xx', 'COMPAREANY isnot'], 656 \ ] 657 if has('float') 658 cases->extend([ 659 \ ['1.1 == 2.2', 'COMPAREFLOAT =='], 660 \ ['1.1 != 2.2', 'COMPAREFLOAT !='], 661 \ ['1.1 > 2.2', 'COMPAREFLOAT >'], 662 \ ['1.1 < 2.2', 'COMPAREFLOAT <'], 663 \ ['1.1 >= 2.2', 'COMPAREFLOAT >='], 664 \ ['1.1 <= 2.2', 'COMPAREFLOAT <='], 665 \ ['1.1 =~ 2.2', 'COMPAREFLOAT =\~'], 666 \ ['1.1 !~ 2.2', 'COMPAREFLOAT !\~'], 667 \ ]) 668 endif 669 670 let nr = 1 671 for case in cases 672 writefile(['def TestCase' .. nr .. '()', 673 \ ' if ' .. case[0], 674 \ ' echo 42' 675 \ ' endif', 676 \ 'enddef'], 'Xdisassemble') 677 source Xdisassemble 678 let instr = execute('disassemble TestCase' .. nr) 679 assert_match('TestCase' .. nr .. '.*' 680 \ .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' 681 \ .. '\d \(PUSH\|FUNCREF\).*' 682 \ .. '\d \(PUSH\|FUNCREF\|LOADG\).*' 683 \ .. '\d ' .. case[1] .. '.*' 684 \ .. '\d JUMP_IF_FALSE -> \d\+.*' 685 \, instr) 686 687 nr += 1 688 endfor 689 690 " delete('Xdisassemble') 691enddef 692 693" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 694