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