• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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});