Beispiel #1
0
 def testExpressionMultiplicationPrecedence(self):
     ast = Parser().parseTopLevel('2+3*4-9')
     self._assertBody(ast, [
         'Binop', '-',
         [
             'Binop', '+', ['Double', '2'],
             ['Binop', '*', ['Double', '3'], ['Double', '4']]
         ], ['Double', '9']
     ])
Beispiel #2
0
 def testFunctionDefinition(self):
     ast = Parser().parseTopLevel('func foo(x) 1 + bar(x)')
     self.assertEqual(self._flatten(ast), [
         'Function', ['Proto', 'foo', 'x'],
         [
             'Binop', '+', ['Double', '1'],
             ['Call', 'bar', [['Variable', 'x']]]
         ]
     ])
Beispiel #3
0
 def testExpressionParentheses(self):
     ast = Parser().parseTopLevel('2*(3-4)*7')
     self._assertBody(ast, [
         'Binop', '*',
         [
             'Binop', '*', ['Double', '2'],
             ['Binop', '-', ['Double', '3'], ['Double', '4']]
         ], ['Double', '7']
     ])
Beispiel #4
0
    def evaluate(self, codeString, optimize=True, llvmdump=False):
        """
        Evaluate code in codestr.

        Returns 0.0 for definitions and import, and the evaluated expression
        value for toplevel expressions.
        """
        # Parse the given code and generate code from it
        ast = Parser().parseTopLevel(codeString)
        self.codegen.generateCode(ast)
        test = type(ast)

        if llvmdump:
            print('======== Unoptimized LLVM IR')
            print(str(self.codegen.module))

        # If we're evaluating a definition or import declaration, don't do
        # anything else. If we're evaluating an anonymous wrapper for a toplevel
        # expression, JIT-compile the module and run the function to get its
        # result.
        llvmmod = llvm.parse_assembly(str(self.codegen.module))

        #Optimize the module
        if optimize:
            pmb = llvm.create_pass_manager_builder()
            pmb.opt_level = 2
            pm = llvm.create_module_pass_manager()
            pmb.populate(pm)
            pm.run(llvmmod)

            if llvmdump:
                print('======== Optimized LLVM IR')
                print(str(llvmmod))

        # Create a MCJIT execution engine to JIT-compile the module. Note that
        # ee takes ownership of target_machine, so it has to be recreated anew
        # each time we call create_mcjit_compiler.
        targetMachine = self.target.create_target_machine()
        with llvm.create_mcjit_compiler(llvmmod,
                                        targetMachine) as mcjitCompiler:
            mcjitCompiler.finalize_object()

            if llvmdump:
                print('======== Machine code')
                print(targetMachine.emit_assembly(llvmmod))

            result = 0.0
            if type(ast) == FunctionAST:
                functionPointer = CFUNCTYPE(c_double)(
                    mcjitCompiler.get_function_address(ast.proto.name))
                result = functionPointer()
            return result
Beispiel #5
0
 def testExpressionSinglePrecedent(self):
     ast = Parser().parseTopLevel('2 + 3 - 4')
     self._assertBody(ast, [
         'Binop', '-', ['Binop', '+', ['Double', '2'], ['Double', '3']],
         ['Double', '4']
     ])
Beispiel #6
0
 def testBasicWithFlattening(self):
     ast = Parser().parseTopLevel('2')
     self._assertBody(ast, ['Double', '2'])
     ast = Parser().parseTopLevel('foobar')
     self._assertBody(ast, ['Variable', 'foobar'])
Beispiel #7
0
 def testBasic(self):
     ast = Parser().parseTopLevel('2')
     self.assertIsInstance(ast, FunctionAST)
     self.assertIsInstance(ast.body, DoubleExprAST)
     self.assertEqual(ast.body.val, '2')
Beispiel #8
0
 def testImports(self):
     ast = Parser().parseTopLevel('import sin(arg)')
     self.assertEqual(self._flatten(ast), ['Proto', 'sin', 'arg'])
     ast = Parser().parseTopLevel('import Foobar(nom denom abom)')
     self.assertEqual(self._flatten(ast),
                      ['Proto', 'Foobar', 'nom denom abom'])