• 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    And2,
22    Eq,
23    Greater,
24    Greatereq,
25    Inc,
26    Instanceof,
27    Isin,
28    Less,
29    Lesseq,
30    Noteq,
31    Or2,
32    Returnundefined,
33    Sttoglobalrecord,
34    Stricteq,
35    Strictnoteq,
36    Tonumeric,
37    Tryldglobalbyname,
38    Trystglobalbyname,
39    Xor2,
40    Imm,
41    Jeqz,
42    Jmp,
43    Label,
44    Lda,
45    Ldai,
46    LdaStr,
47    Sta,
48    VReg,
49    IRNode
50} from "../../src/irnodes";
51import { checkInstructions, compileMainSnippet } from "../utils/base";
52import { creatAstFromSnippet } from "../utils/asthelper";
53import { PandaGen } from '../../src/pandagen';
54
55describe("CmpBinaryOperators", function () {
56    it("LessThan", function () {
57        let insns = compileMainSnippet("2 < 3;");
58        IRNode.pg = new PandaGen("foo", creatAstFromSnippet("2 < 3;"), 0, undefined);
59        let lhs = new VReg();
60        let falseLabel = new Label();
61        let endLabel = new Label();
62
63        let expected = [
64            new Ldai(new Imm(2)),
65            new Sta(lhs),
66            new Ldai(new Imm(3)),
67            new Less(new Imm(0), lhs),
68            new Jeqz(falseLabel),
69            new Lda(new VReg()),
70            new Jmp(endLabel),
71            falseLabel,
72            new Lda(new VReg()),
73            endLabel,
74            new Returnundefined()
75        ];
76        expect(checkInstructions(insns, expected)).to.be.true;
77    });
78
79    it("GreaterThan", function () {
80        let insns = compileMainSnippet("3 > 1;");
81        IRNode.pg = new PandaGen("foo", creatAstFromSnippet("3 > 1;"), 0, undefined);
82        let lhs = new VReg();
83        let falseLabel = new Label();
84        let endLabel = new Label();
85
86        let expected = [
87            new Ldai(new Imm(3)),
88            new Sta(lhs),
89            new Ldai(new Imm(1)),
90            new Greater(new Imm(0), lhs),
91            new Jeqz(falseLabel),
92            new Lda(new VReg()),
93            new Jmp(endLabel),
94            falseLabel,
95            new Lda(new VReg()),
96            endLabel,
97            new Returnundefined()
98        ];
99        expect(checkInstructions(insns, expected)).to.be.true;
100    });
101
102    it("LessThanEquals", function () {
103        let insns = compileMainSnippet("3 <= 4;");
104        IRNode.pg = new PandaGen("foo", creatAstFromSnippet("3 <= 4;"), 0, undefined);
105        let lhs = new VReg();
106        let falseLabel = new Label();
107        let endLabel = new Label();
108
109        let expected = [
110            new Ldai(new Imm(3)),
111            new Sta(lhs),
112            new Ldai(new Imm(4)),
113            new Lesseq(new Imm(0), lhs),
114            new Jeqz(falseLabel),
115            new Lda(new VReg()),
116            new Jmp(endLabel),
117            falseLabel,
118            new Lda(new VReg()),
119            endLabel,
120            new Returnundefined()
121        ];
122        expect(checkInstructions(insns, expected)).to.be.true;
123    });
124
125    it("GreaterThanEquals", function () {
126        let insns = compileMainSnippet("3 >= 2;");
127        IRNode.pg = new PandaGen("foo", creatAstFromSnippet("3 >= 2;"), 0, undefined);
128        let lhs = new VReg();
129        let falseLabel = new Label();
130        let endLabel = new Label();
131
132        let expected = [
133            new Ldai(new Imm(3)),
134            new Sta(lhs),
135            new Ldai(new Imm(2)),
136            new Greatereq(new Imm(0), lhs),
137            new Jeqz(falseLabel),
138            new Lda(new VReg()),
139            new Jmp(endLabel),
140            falseLabel,
141            new Lda(new VReg()),
142            endLabel,
143            new Returnundefined()
144        ];
145        expect(checkInstructions(insns, expected)).to.be.true;
146    });
147
148    it("EqualsEquals", function () {
149        let insns = compileMainSnippet("3 == 3;");
150        IRNode.pg = new PandaGen("foo", creatAstFromSnippet("3 == 3;"), 0, undefined);
151        let lhs = new VReg();
152        let falseLabel = new Label();
153        let endLabel = new Label();
154
155        let expected = [
156            new Ldai(new Imm(3)),
157            new Sta(lhs),
158            new Ldai(new Imm(3)),
159            new Eq(new Imm(0), lhs),
160            new Jeqz(falseLabel),
161            new Lda(new VReg()),
162            new Jmp(endLabel),
163            falseLabel,
164            new Lda(new VReg()),
165            endLabel,
166            new Returnundefined()
167        ];
168        expect(checkInstructions(insns, expected)).to.be.true;
169    });
170
171    it("ExclamationEquals", function () {
172        let insns = compileMainSnippet("3 != 2;");
173        IRNode.pg = new PandaGen("foo", creatAstFromSnippet("3 != 2;"), 0, undefined);
174        let lhs = new VReg();
175        let falseLabel = new Label();
176        let endLabel = new Label();
177
178        let expected = [
179            new Ldai(new Imm(3)),
180            new Sta(lhs),
181            new Ldai(new Imm(2)),
182            new Noteq(new Imm(0), lhs),
183            new Jeqz(falseLabel),
184            new Lda(new VReg()),
185            new Jmp(endLabel),
186            falseLabel,
187            new Lda(new VReg()),
188            endLabel,
189            new Returnundefined()
190        ];
191        expect(checkInstructions(insns, expected)).to.be.true;
192    });
193
194    it("EqualsEqualsEquals", function () {
195        let insns = compileMainSnippet("3 === 3;");
196        IRNode.pg = new PandaGen("foo", creatAstFromSnippet("3 === 3;"), 0, undefined);
197        let lhs = new VReg();
198        let falseLabel = new Label();
199        let endLabel = new Label();
200
201        let expected = [
202            new Ldai(new Imm(3)),
203            new Sta(lhs),
204            new Ldai(new Imm(3)),
205            new Stricteq(new Imm(0), lhs),
206            new Jeqz(falseLabel),
207            new Lda(new VReg()),
208            new Jmp(endLabel),
209            falseLabel,
210            new Lda(new VReg()),
211            endLabel,
212            new Returnundefined()
213        ];
214        expect(checkInstructions(insns, expected)).to.be.true;
215    });
216
217    it("ExclamationEqualsEquals", function () {
218        let insns = compileMainSnippet("3 !== 3;");
219        IRNode.pg = new PandaGen("foo", creatAstFromSnippet("3 !== 3;"), 0, undefined);
220        let lhs = new VReg();
221        let falseLabel = new Label();
222        let endLabel = new Label();
223
224        let expected = [
225            new Ldai(new Imm(3)),
226            new Sta(lhs),
227            new Ldai(new Imm(3)),
228            new Strictnoteq(new Imm(0), lhs),
229            new Jeqz(falseLabel),
230            new Lda(new VReg()),
231            new Jmp(endLabel),
232            falseLabel,
233            new Lda(new VReg()),
234            endLabel,
235            new Returnundefined()
236        ];
237        expect(checkInstructions(insns, expected)).to.be.true;
238    });
239
240    it("ampersandEqual", function () {
241        let insns = compileMainSnippet("let a = 5;\n" +
242            "a &= 3;");
243        IRNode.pg = new PandaGen("foo", creatAstFromSnippet("let a = 5;\n" + "a &= 3;"), 0, undefined);
244        let lhs = new VReg();
245
246        let expected = [
247            new Ldai(new Imm(5)),
248            new Sttoglobalrecord(new Imm(0), 'a'),
249            new Tryldglobalbyname(new Imm(1), 'a'),
250            new Sta(lhs),
251            new Ldai(new Imm(3)),
252            new And2(new Imm(2), lhs),
253            new Trystglobalbyname(new Imm(3), 'a'),
254            new Returnundefined()
255        ];
256        expect(checkInstructions(insns, expected)).to.be.true;
257    });
258
259    it("barEqual", function () {
260        let insns = compileMainSnippet("let a = 5;\n" +
261            "a |= 3;");
262        IRNode.pg = new PandaGen("foo", creatAstFromSnippet("let a = 5;\n" + "a |= 3;"), 0, undefined);
263        let lhs = new VReg();
264
265        let expected = [
266            new Ldai(new Imm(5)),
267            new Sttoglobalrecord(new Imm(0), 'a'),
268            new Tryldglobalbyname(new Imm(1), 'a'),
269            new Sta(lhs),
270            new Ldai(new Imm(3)),
271            new Or2(new Imm(2), lhs),
272            new Trystglobalbyname(new Imm(3), 'a'),
273            new Returnundefined()
274        ];
275        expect(checkInstructions(insns, expected)).to.be.true;
276    });
277
278    it("caretEqual", function () {
279        let insns = compileMainSnippet("let a = 5;\n" +
280            "a ^= 3;");
281        IRNode.pg = new PandaGen("foo", creatAstFromSnippet("let a = 5;\n" + "a ^= 3;"), 0, undefined);
282        let lhs = new VReg();
283
284        let expected = [
285            new Ldai(new Imm(5)),
286            new Sttoglobalrecord(new Imm(0), 'a'),
287            new Tryldglobalbyname(new Imm(1), 'a'),
288            new Sta(lhs),
289            new Ldai(new Imm(3)),
290            new Xor2(new Imm(2), lhs),
291            new Trystglobalbyname(new Imm(3), 'a'),
292            new Returnundefined()
293        ];
294        expect(checkInstructions(insns, expected)).to.be.true;
295    });
296
297    it("CommaToken", function () {
298        let insns = compileMainSnippet(`let x = 1;
299                                x = (x++, x);`);
300        IRNode.pg = new PandaGen("foo", creatAstFromSnippet(`let x = 1; x = (x++, x);`), 0, undefined);
301        let rhs = new VReg();
302        let lhs = new VReg();
303
304        let expected = [
305            new Ldai(new Imm(1)),
306            new Sttoglobalrecord(new Imm(0), 'x'),
307            new Tryldglobalbyname(new Imm(1), 'x'),
308            new Sta(lhs),
309            new Lda(lhs),
310            new Inc(new Imm(2)),
311            new Trystglobalbyname(new Imm(3), 'x'),
312            new Lda(new VReg()),
313            new Tonumeric(new Imm(4)),
314            new Sta(rhs),
315            new Tryldglobalbyname(new Imm(5), 'x'),
316            new Trystglobalbyname(new Imm(6), 'x'),
317            new Returnundefined()
318        ];
319        expect(checkInstructions(insns, expected)).to.be.true;
320    });
321
322    it("InKeyword", function () {
323        let insns = compileMainSnippet(`'o' in C;`);
324        IRNode.pg = new PandaGen("foo", creatAstFromSnippet(`'o' in C;`), 0, undefined);
325        let rhs = new VReg();
326
327        let expected = [
328            new LdaStr('o'),
329            new Sta(rhs),
330            new Tryldglobalbyname(new Imm(0), "C"),
331            new Isin(new Imm(1), rhs),
332            new Returnundefined()
333        ];
334        expect(checkInstructions(insns, expected)).to.be.true;
335    });
336
337    it("InstanceOfKeyword", function () {
338        let insns = compileMainSnippet(`o instanceof C;`);
339        IRNode.pg = new PandaGen("foo", creatAstFromSnippet(`o instanceof C;`), 0, undefined);
340        let rhs = new VReg();
341
342        let expected = [
343            new Tryldglobalbyname(new Imm(0), "o"),
344            new Sta(rhs),
345            new Tryldglobalbyname(new Imm(1), "C"),
346            new Instanceof(new Imm(2), rhs),
347            new Returnundefined()
348        ];
349        expect(checkInstructions(insns, expected)).to.be.true;
350    });
351
352});
353