1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { 17 expect 18} from 'chai'; 19import 'mocha'; 20import { 21 Less, 22 Returnundefined, 23 Sttoglobalrecord, 24 Tryldglobalbyname, 25 Trystglobalbyname, 26 Imm, 27 Jeqz, 28 Jmp, 29 Label, 30 Ldai, 31 Sta, 32 VReg, 33 IRNode 34} from "../../src/irnodes"; 35import { checkInstructions, compileMainSnippet } from "../utils/base"; 36import { creatAstFromSnippet } from "../utils/asthelper" 37import { PandaGen } from '../../src/pandagen'; 38 39describe("DoWhileLoopTest", function () { 40 it('doWhileLoopEmpty', function () { 41 let insns = compileMainSnippet("do {} while (true)"); 42 43 let jumps = insns.filter(item => item instanceof Jmp); 44 45 expect(jumps.length).to.equal(1); 46 47 let jmpLabel = (<Jmp>jumps[0]).getTarget(); 48 49 expect(jmpLabel).to.equal(insns[0]); 50 }); 51 52 it('doWhileLoopWithBody', function () { 53 let insns = compileMainSnippet("let a = 5;" + 54 "do { a++ } while (a < 11);"); 55 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 56 let jumps = insns.filter(item => (item instanceof Jmp || item instanceof Jeqz)); 57 58 expect(jumps.length).to.equal(2); 59 60 let jgezLabel = (<Jmp>jumps[0]).getTarget(); 61 let jmpLabel = (<Jmp>jumps[1]).getTarget(); 62 63 expect(jmpLabel).to.equal(insns[2]); 64 expect(jgezLabel).to.equal(insns[17]); 65 66 expect(insns[15]).to.equal(jumps[0]); 67 expect(insns[16]).to.equal(jumps[1]); 68 }); 69 70 it('doWhileLoopWithContinue', function () { 71 let insns = compileMainSnippet("let a = 5;" + 72 "do { a = 1; continue; } while (a < 1);"); 73 let lhs = new VReg(); 74 let labelPre = new Label(); 75 let labelCond = new Label(); 76 let labelPost = new Label(); 77 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 78 let expected = [ 79 new Ldai(new Imm(5)), 80 new Sttoglobalrecord(new Imm(0), 'a'), 81 // body 82 labelPre, 83 new Ldai(new Imm(1)), 84 new Trystglobalbyname(new Imm(1), 'a'), 85 new Jmp(labelCond), // continue 86 // condition 87 labelCond, 88 new Tryldglobalbyname(new Imm(2), 'a'), 89 new Sta(lhs), 90 new Ldai(new Imm(1)), 91 new Less(new Imm(3), lhs), 92 new Jeqz(labelPost), 93 new Jmp(labelPre), 94 labelPost, 95 new Returnundefined() 96 ] 97 98 // check the instruction kinds are the same as we expect 99 expect(checkInstructions(insns, expected)).to.be.true; 100 // check continue jumps to the expected instruction 101 let jmp = <Jmp>insns[5]; 102 let targetLabel = (jmp).getTarget(); 103 expect(targetLabel).to.equal(insns[6]); 104 }); 105 106 it('doWhileLoopWithBreak', function () { 107 let insns = compileMainSnippet("let a = 5;" + 108 "do { a = 1; break; } while (a < 1);"); 109 let lhs = new VReg(); 110 let labelPre = new Label(); 111 let labelPost = new Label(); 112 let labelCond = new Label(); 113 IRNode.pg = new PandaGen("", creatAstFromSnippet(``), 0, undefined); 114 let expected = [ 115 new Ldai(new Imm(5)), 116 new Sttoglobalrecord(new Imm(0), 'a'), 117 //body 118 labelPre, 119 new Ldai(new Imm(1)), 120 new Trystglobalbyname(new Imm(1), 'a'), 121 new Jmp(labelPost), // break 122 // condition 123 labelCond, 124 new Tryldglobalbyname(new Imm(2), 'a'), 125 new Sta(lhs), 126 new Ldai(new Imm(1)), 127 new Less(new Imm(3), lhs), 128 new Jeqz(labelPost), 129 new Jmp(labelPre), 130 labelPost, 131 new Returnundefined() 132 ] 133 134 // check the instruction kinds are the same as we expect 135 expect(checkInstructions(insns, expected)).to.be.true; 136 // check continue jumps to the expected instruction 137 let jmp = <Jmp>insns[5]; 138 let targetLabel = (jmp).getTarget(); 139 expect(targetLabel).to.equal(insns[13]); 140 }); 141});