Exemple #1
0
    def test_loops(self):
        helper = CompileHelper(self, 'let a = 1; while (a < 10) { a = a + 1; }; a')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0), #0000
            makeInstr(OPSETGLOBAL, 0), #0003
            makeInstr(OPCONSTANT, 1), #0006
            makeInstr(OPGETGLOBAL, 0), #0009
            makeInstr(OPGT), #0012
            makeInstr(OPJUMPNOTTRUE, 25), #0013
            makeInstr(OPCLOSURE, 3, 0), #0016
            makeInstr(OPLOOPCALL, 0), #0019
            makeInstr(OPJUMP, 6), #0021
            makeInstr(OPGETGLOBAL, 0), #0024
            makeInstr(OPPOP),
        ])
        helper.checkConstantsExpected([
            1,
            10,
            1,
            b''.join([
                makeInstr(OPGETGLOBAL, 0), #0009
                makeInstr(OPCONSTANT, 2), #0016
                makeInstr(OPADD), #0016
                makeInstr(OPSETGLOBAL, 0), #0016
                makeInstr(OPCONTINUE), #0000
            ])
        ])

        helper = CompileHelper(self, 'let c = 0; let a = [1, 2, 3]; for (i in a) { c = c + i; }')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0), #let c = 0;
            makeInstr(OPSETGLOBAL, 0),
            makeInstr(OPCONSTANT, 1), #let a = [1, 2, 3];
            makeInstr(OPCONSTANT, 2),
            makeInstr(OPCONSTANT, 3),
            makeInstr(OPARRAY, 3),
            makeInstr(OPSETGLOBAL, 1),
            makeInstr(OPGETGLOBAL, 1), #let <iter> = iter(a);
            makeInstr(OPITER),
            makeInstr(OPSETGLOBAL, 2),
            makeInstr(OPGETGLOBAL, 2), #0028 if <iter>.hasNext()
            makeInstr(OPITERHASNEXT),
            makeInstr(OPJUMPNOTTRUE, 48),
            makeInstr(OPCLOSURE, 4, 0), #<for block>
            makeInstr(OPGETGLOBAL, 2), #iter.next()
            makeInstr(OPITERNEXT),
            makeInstr(OPLOOPCALL, 1), #<for block>()
            makeInstr(OPJUMP, 28),
        ])
Exemple #2
0
 def test_hashes(self):
     helper = CompileHelper(self, '{1:2+3, 4:5*6}[0]')
     helper.checkInstructionsExpected([
         makeInstr(OPCONSTANT, 0), #0000
         makeInstr(OPCONSTANT, 1), #0000
         makeInstr(OPCONSTANT, 2), #0000
         makeInstr(OPADD), #0000
         makeInstr(OPCONSTANT, 3), #0000
         makeInstr(OPCONSTANT, 4), #0000
         makeInstr(OPCONSTANT, 5), #0000
         makeInstr(OPMUL), #0000
         makeInstr(OPHASH, 4),
         makeInstr(OPCONSTANT, 6),
         makeInstr(OPINDEX),
         makeInstr(OPPOP), #0012
     ])
Exemple #3
0
 def test_opconstant(self):
     helper = CompileHelper(self, '3 + 5')
     helper.checkInstructionsExpected([
         makeInstr(OPCONSTANT, 0),
         makeInstr(OPCONSTANT, 1),
         makeInstr(OPADD),
         makeInstr(OPPOP),
     ])
     helper.checkConstantsExpected([3, 5])
Exemple #4
0
    def test_classes(self):
        helper = CompileHelper(self, 'class A {}')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0),
            makeInstr(OPDEFCLASS, 0, 0, 0),
        ])

        helper = CompileHelper(self, 'class A { m1(x) {}; m2(y, z) {}; m3(a) {} }')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0),
            makeInstr(OPCLOSURE, 1, 0),
            makeInstr(OPCONSTANT, 2),
            makeInstr(OPCLOSURE, 3, 0),
            makeInstr(OPCONSTANT, 4),
            makeInstr(OPCLOSURE, 5, 0),
            makeInstr(OPCONSTANT, 6),
            makeInstr(OPDEFCLASS, 0, 0, 6),
        ])
Exemple #5
0
    def test_codeGenConstantIO(self):
        codeBlocks = [
            'let g = 10; let s = fn(a, b){ let c = a+b; c + g;}; let outer = fn() { s(1, 2)+ s(3, 4)+g;};'
        ]

        for code in codeBlocks:
            helper = CompileHelper(self, code)
            constants = helper.bytecode.constants
            deflatedConstants = [deflate(c) for c in constants]
            inflatedConstantPairs = [inflate(c) for c in deflatedConstants]

            for origConstant, inflatedConstantPair in zip(
                    constants, inflatedConstantPairs):
                inflatedConstant, bytesInflated = inflatedConstantPair
                self.assertEqual(origConstant.objectType,
                                 inflatedConstant.objectType)
                self.assertEqual(origConstant.inspect(),
                                 inflatedConstant.inspect())
Exemple #6
0
    def test_functionIO(self):
        fndefs = [
            ('fn() { let a = 55; let b = 77; a + b }', 2),
            ('fn() { return 5 + 10 }', 2),
        ]

        for fndef, constantIndex in fndefs:
            helper = CompileHelper(self, fndef)
            fn = helper.bytecode.constants[2]
            deflatedFn = deflate(fn)
            inflatedFn, bytesRead = inflate(deflatedFn)
            self.assertEqual(bytesRead, len(deflatedFn))
            self.assertEqual(fn.objectType, inflatedFn.objectType)
            self.assertEqual(fn.objectType,
                             OBJECT_TYPES.OBJECT_TYPE_COMPILED_FUNCTION)
            self.assertEqual(fn.instr, inflatedFn.instr)
            self.assertEqual(fn.numLocals, inflatedFn.numLocals)
            self.assertEqual(fn.numParameters, inflatedFn.numParameters)
            self.assertEqual(fn.inspect(), inflatedFn.inspect())
Exemple #7
0
 def test_codeIO(self):
     codeBlocks = [
         'let g = 10; let s = fn(a, b){ let c = a+b; c + g;}; let outer = fn() { s(1, 2)+ s(3, 4)+g;};',
         'let c = 0; let a  = [1, 2, 3, 4, 5]; for (i in a) { c = c + i; if (i > 3) { break;} }; c',
     ]
     for code in codeBlocks:
         helper = CompileHelper(self, code)
         writer = BytecodeWriter(helper.bytecode)
         instr = writer.write()
         reader = BytecodeReader(instr)
         reader.read()
         self.assertEqual(BUILD_NUMBER, reader.readBuildNumber)
         self.assertEqual(VERSION_STRING, reader.readVersionString)
         self.assertEqual(len(helper.bytecode.constants),
                          len(reader.constants))
         for origConstant, inflatedConstant in zip(
                 helper.bytecode.constants, reader.constants):
             self.assertEqual(origConstant.objectType,
                              inflatedConstant.objectType)
             self.assertEqual(origConstant.inspect(),
                              inflatedConstant.inspect())
         self.assertEqual(helper.bytecode.instr, reader.codeInstr)
Exemple #8
0
    def test_simpleExpressions(self):
        helper = CompileHelper(self, '"abcd"')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0),
            makeInstr(OPPOP),
        ])

        helper = CompileHelper(self, '"abcd" + "defg"')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0),
            makeInstr(OPCONSTANT, 1),
            makeInstr(OPADD),
            makeInstr(OPPOP),
        ])

        helper = CompileHelper(self, '3 + 5; 2; true; false')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0),
            makeInstr(OPCONSTANT, 1),
            makeInstr(OPADD),
            makeInstr(OPPOP),
            makeInstr(OPCONSTANT, 2),
            makeInstr(OPPOP),
            makeInstr(OPTRUE),
            makeInstr(OPPOP),
            makeInstr(OPFALSE),
            makeInstr(OPPOP),
        ])
        helper.checkConstantsExpected([3, 5, 2])

        helper = CompileHelper(self, '1 < 2')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0),
            makeInstr(OPCONSTANT, 1),
            makeInstr(OPGT),
            makeInstr(OPPOP),
        ])

        helper = CompileHelper(self, '-5')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0),
            makeInstr(OPMINUS),
            makeInstr(OPPOP),
        ])
Exemple #9
0
    def test_functions(self):
        helper = CompileHelper(self, 'fn() { return 5 + 10 }')
        helper.checkConstantsExpected([
            5,
            10,
            b''.join([
                makeInstr(OPCONSTANT, 0), #0000
                makeInstr(OPCONSTANT, 1), #0000
                makeInstr(OPADD), #0000
                makeInstr(OPRETURNVALUE), #0000
            ])
        ])

        helper = CompileHelper(self, 'fn() { 5 + 10 }')
        helper.checkConstantsExpected([
            5,
            10,
            b''.join([
                makeInstr(OPCONSTANT, 0), #0000
                makeInstr(OPCONSTANT, 1), #0000
                makeInstr(OPADD), #0000
                makeInstr(OPRETURNVALUE), #0000
            ])
        ])

        helper = CompileHelper(self, 'fn() {  }')
        helper.checkConstantsExpected([
            b''.join([
                makeInstr(OPNULL), #0000
                makeInstr(OPRETURNVALUE), #0000
            ])
        ])

        helper = CompileHelper(self, 'let num = 55; fn() { num }')
        helper.checkConstantsExpected([
            55,
            b''.join([
                makeInstr(OPGETGLOBAL, 0), #0000
                makeInstr(OPRETURNVALUE), #0000
            ])
        ])

        helper = CompileHelper(self, 'fn() { let num = 55; num }')
        helper.checkConstantsExpected([
            55,
            b''.join([
                makeInstr(OPCONSTANT, 0),
                makeInstr(OPSETLOCAL, 0), #0000
                makeInstr(OPGETLOCAL, 0), #0000
                makeInstr(OPRETURNVALUE), #0000
            ])
        ])

        helper = CompileHelper(self, 'fn() { let a = 55; let b = 77; a + b }')
        helper.checkConstantsExpected([
            55,
            77,
            b''.join([
                makeInstr(OPCONSTANT, 0),
                makeInstr(OPSETLOCAL, 0), #0000
                makeInstr(OPCONSTANT, 1),
                makeInstr(OPSETLOCAL, 1), #0000
                makeInstr(OPGETLOCAL, 0), #0000
                makeInstr(OPGETLOCAL, 1), #0000
                makeInstr(OPADD), #0000
                makeInstr(OPRETURNVALUE), #0000
            ])
        ])
Exemple #10
0
    def test_attributes(self):
        helper = CompileHelper(self, 'let a = "abc"; a.length')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0),
            makeInstr(OPSETGLOBAL, 0),
            makeInstr(OPGETGLOBAL, 0),
            makeInstr(OPCONSTANT, 1),
            makeInstr(OPGETATTR),
            makeInstr(OPPOP),
        ])

        helper = CompileHelper(self, 'let a = "abc"; a.length.length')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0),
            makeInstr(OPSETGLOBAL, 0),
            makeInstr(OPGETGLOBAL, 0),
            makeInstr(OPCONSTANT, 1),
            makeInstr(OPGETATTR),
            makeInstr(OPCONSTANT, 2),
            makeInstr(OPGETATTR),
            makeInstr(OPPOP),
        ])

        helper = CompileHelper(self, 'let a = "abc"; a[0].length[0]')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0),
            makeInstr(OPSETGLOBAL, 0),
            makeInstr(OPGETGLOBAL, 0),
            makeInstr(OPCONSTANT, 1),
            makeInstr(OPINDEX),
            makeInstr(OPCONSTANT, 2),
            makeInstr(OPGETATTR),
            makeInstr(OPCONSTANT, 3),
            makeInstr(OPINDEX),
            makeInstr(OPPOP),
        ])
Exemple #11
0
    def test_arrays(self):
        helper = CompileHelper(self, '[]')
        helper.checkInstructionsExpected([
            makeInstr(OPARRAY, 0), #0009
            makeInstr(OPPOP), #0012
        ])

        helper = CompileHelper(self, '[1, 2, 3]')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0), #0000
            makeInstr(OPCONSTANT, 1), #0003
            makeInstr(OPCONSTANT, 2), #0006
            makeInstr(OPARRAY, 3), #0009
            makeInstr(OPPOP), #0012
        ])

        helper = CompileHelper(self, '[1, 1 + 2]')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0), #0000
            makeInstr(OPCONSTANT, 1), #0003
            makeInstr(OPCONSTANT, 2), #0006
            makeInstr(OPADD),
            makeInstr(OPARRAY, 2), #0009
            makeInstr(OPPOP), #0012
        ])

        helper = CompileHelper(self, '[1, 1 + 2][0]')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0), #0000
            makeInstr(OPCONSTANT, 1), #0003
            makeInstr(OPCONSTANT, 2), #0006
            makeInstr(OPADD),
            makeInstr(OPARRAY, 2), #0009
            makeInstr(OPCONSTANT, 3),
            makeInstr(OPINDEX),
            makeInstr(OPPOP), #0012
        ])

        helper = CompileHelper(self, 'let a = [1, 2]; a[0] = 3;')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0), #0000
            makeInstr(OPCONSTANT, 1), #0000
            makeInstr(OPARRAY, 2), #0009
            makeInstr(OPSETGLOBAL, 0),
            makeInstr(OPGETGLOBAL, 0),
            makeInstr(OPCONSTANT, 2), #0000
            makeInstr(OPCONSTANT, 3), #0000
            makeInstr(OPSETINDEX),
        ])
Exemple #12
0
    def test_letsAndIdents(self):
        helper = CompileHelper(self, 'let a = 1; let b = 2;')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0), #0000
            makeInstr(OPSETGLOBAL, 0), #0003
            makeInstr(OPCONSTANT, 1), #0006
            makeInstr(OPSETGLOBAL, 1), #0009
        ])

        helper = CompileHelper(self, 'let a = 1; a + 1')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0), #0000
            makeInstr(OPSETGLOBAL, 0), #0003
            makeInstr(OPGETGLOBAL, 0), #0006
            makeInstr(OPCONSTANT, 1), #0009
            makeInstr(OPADD), #0012
            makeInstr(OPPOP), #0013
        ])

        helper = CompileHelper(self, 'let a = 1; let b = a; b = a + 1')
        helper.checkInstructionsExpected([
            makeInstr(OPCONSTANT, 0), #0000
            makeInstr(OPSETGLOBAL, 0), #0003
            makeInstr(OPGETGLOBAL, 0), #0006
            makeInstr(OPSETGLOBAL, 1), #0003
            makeInstr(OPGETGLOBAL, 0), #0006
            makeInstr(OPCONSTANT, 1), #0000
            makeInstr(OPADD), #0012
            makeInstr(OPSETGLOBAL, 1), #0003
        ])
Exemple #13
0
    def test_conditionals(self):
        helper = CompileHelper(self, 'if (true) { 10 }')
        helper.checkInstructionsExpected([
            makeInstr(OPTRUE), #0000
            makeInstr(OPJUMPNOTTRUE, 12), #0001
            makeInstr(OPCLOSURE, 1, 0), #0004
            makeInstr(OPBLOCKCALL), #0007
            makeInstr(OPJUMP, 13), #0008
            makeInstr(OPNULL),#0011
            makeInstr(OPPOP), #0012
        ])
        helper.checkConstantsExpected([
            10,
            b''.join([
                makeInstr(OPCONSTANT, 0),
                makeInstr(OPBLOCKRETURN), #0000
            ])
        ])

        helper = CompileHelper(self, 'if (true) { }')
        helper.checkInstructionsExpected([
            makeInstr(OPTRUE), #0000
            makeInstr(OPJUMPNOTTRUE, 12), #0001
            makeInstr(OPCLOSURE, 0, 0), #0004
            makeInstr(OPBLOCKCALL),
            makeInstr(OPJUMP, 13), #0005
            makeInstr(OPNULL),
            makeInstr(OPPOP), #0009
        ])
        helper.checkConstantsExpected([
            b''.join([
                makeInstr(OPNULL),
                makeInstr(OPBLOCKRETURN), #0000
            ])
        ])

        helper = CompileHelper(self, 'if (true) { 10 } elif (false) { 20 } else { 30 }')
        helper.checkInstructionsExpected([
            makeInstr(OPTRUE), #0000
            makeInstr(OPJUMPNOTTRUE, 12), #0001
            makeInstr(OPCLOSURE, 1, 0), #0004
            makeInstr(OPBLOCKCALL),
            makeInstr(OPJUMP, 29), #0007
            makeInstr(OPFALSE), #0010
            makeInstr(OPJUMPNOTTRUE, 24), #0011
            makeInstr(OPCLOSURE, 3, 0), #0014
            makeInstr(OPBLOCKCALL),
            makeInstr(OPJUMP, 29), #0017
            makeInstr(OPCLOSURE, 5, 0),#0020
            makeInstr(OPBLOCKCALL),
            makeInstr(OPPOP), #0023
        ])

        helper = CompileHelper(self, 'if (true) { 10 } elif (false) {  } else { 30 }')
        helper.checkInstructionsExpected([
            makeInstr(OPTRUE), #0000
            makeInstr(OPJUMPNOTTRUE, 12), #0001
            makeInstr(OPCLOSURE, 1, 0), #0004
            makeInstr(OPBLOCKCALL), #0007
            makeInstr(OPJUMP, 29), #0007
            makeInstr(OPFALSE), #0010
            makeInstr(OPJUMPNOTTRUE, 24), #0011
            makeInstr(OPCLOSURE, 2, 0),#0018
            makeInstr(OPBLOCKCALL), #0007
            makeInstr(OPJUMP, 29), #0015
            makeInstr(OPCLOSURE, 4, 0),#0018
            makeInstr(OPBLOCKCALL), #0007
            makeInstr(OPPOP), #0021
        ])

        helper = CompileHelper(self, 'if (true) { 10 } elif (false) { 20 } else { }')
        helper.checkInstructionsExpected([
            makeInstr(OPTRUE), #0000
            makeInstr(OPJUMPNOTTRUE, 12), #0001
            makeInstr(OPCLOSURE, 1, 0), #0004
            makeInstr(OPBLOCKCALL), #0007
            makeInstr(OPJUMP, 29), #0008
            makeInstr(OPFALSE), #0011
            makeInstr(OPJUMPNOTTRUE, 24), #0012
            makeInstr(OPCLOSURE, 3, 0),#0015
            makeInstr(OPBLOCKCALL), #0018
            makeInstr(OPJUMP, 29), #0019
            makeInstr(OPCLOSURE, 4, 0), #0022
            makeInstr(OPBLOCKCALL), #0025
            makeInstr(OPPOP), #0026
        ])