Exemple #1
0
def test_FunctionPrototype_and_FunctionDefinition():
    vx = Variable(x, type=real)
    vn = Variable(n, type=integer)
    fp1 = FunctionPrototype(real, 'power', [vx, vn])
    assert fp1.return_type == real
    assert fp1.name == String('power')
    assert fp1.parameters == Tuple(vx, vn)
    assert fp1 == FunctionPrototype(real, 'power', [vx, vn])
    assert fp1 != FunctionPrototype(real, 'power', [vn, vx])
    assert fp1.func(*fp1.args) == fp1


    body = [Assignment(x, x**n), Return(x)]
    fd1 = FunctionDefinition(real, 'power', [vx, vn], body)
    assert fd1.return_type == real
    assert str(fd1.name) == 'power'
    assert fd1.parameters == Tuple(vx, vn)
    assert fd1.body == CodeBlock(*body)
    assert fd1 == FunctionDefinition(real, 'power', [vx, vn], body)
    assert fd1 != FunctionDefinition(real, 'power', [vx, vn], body[::-1])
    assert fd1.func(*fd1.args) == fd1

    fp2 = FunctionPrototype.from_FunctionDefinition(fd1)
    assert fp2 == fp1

    fd2 = FunctionDefinition.from_FunctionPrototype(fp1, body)
    assert fd2 == fd1
Exemple #2
0
def test_ccode_codegen_ast():
    assert ccode(Comment("this is a comment")) == "// this is a comment"
    assert ccode(While(abs(x) > 1,
                       [aug_assign(x, '-', 1)])) == ('while (fabs(x) > 1) {\n'
                                                     '   x -= 1;\n'
                                                     '}')
    assert ccode(Scope([AddAugmentedAssignment(x, 1)])) == ('{\n'
                                                            '   x += 1;\n'
                                                            '}')
    inp_x = Declaration(Variable(x, type=real))
    assert ccode(FunctionPrototype(real, 'pwer',
                                   [inp_x])) == 'double pwer(double x)'
    assert ccode(
        FunctionDefinition(
            real, 'pwer', [inp_x],
            [Assignment(x, x**2)])) == ('double pwer(double x){\n'
                                        '   x = pow(x, 2);\n'
                                        '}')

    # Elements of CodeBlock are formatted as statements:
    block = CodeBlock(
        x,
        Print([x, y], "%d %d"),
        FunctionCall('pwer', [x]),
        Return(x),
    )
    assert ccode(block) == '\n'.join([
        'x;',
        'printf("%d %d", x, y);',
        'pwer(x);',
        'return x;',
    ])
Exemple #3
0
    def test_function():
        c_src1 = "void fun1()" + "\n" + "{" + "\n" + "int a;" + "\n" + "}"
        c_src2 = ("int fun2()" + "\n" + "{" + "\n" + "int a;" + "\n" +
                  "return a;" + "\n" + "}")
        c_src3 = ("float fun3()" + "\n" + "{" + "\n" + "float b;" + "\n" +
                  "return b;" + "\n" + "}")
        c_src4 = "float fun4()" + "\n" + "{}"

        res1 = SymPyExpression(c_src1, "c").return_expr()
        res2 = SymPyExpression(c_src2, "c").return_expr()
        res3 = SymPyExpression(c_src3, "c").return_expr()
        res4 = SymPyExpression(c_src4, "c").return_expr()

        assert res1[0] == FunctionDefinition(
            NoneToken(),
            name=String("fun1"),
            parameters=(),
            body=CodeBlock(
                Declaration(
                    Variable(
                        Symbol("a"),
                        type=IntBaseType(String("integer")),
                        value=Integer(0),
                    ))),
        )

        assert res2[0] == FunctionDefinition(
            IntBaseType(String("integer")),
            name=String("fun2"),
            parameters=(),
            body=CodeBlock(
                Declaration(
                    Variable(
                        Symbol("a"),
                        type=IntBaseType(String("integer")),
                        value=Integer(0),
                    )),
                Return("a"),
            ),
        )

        assert res3[0] == FunctionDefinition(
            FloatBaseType(String("real")),
            name=String("fun3"),
            parameters=(),
            body=CodeBlock(
                Declaration(
                    Variable(
                        Symbol("b"),
                        type=FloatBaseType(String("real")),
                        value=Float("0.0", precision=53),
                    )),
                Return("b"),
            ),
        )

        assert res4[0] == FunctionPrototype(FloatBaseType(String("real")),
                                            name=String("fun4"),
                                            parameters=())
Exemple #4
0
def test_FunctionPrototype_print():
    x = symbols('x')
    n = symbols('n', integer=True)
    vx = Variable(x, type=real)
    vn = Variable(n, type=integer)
    fp1 = FunctionPrototype(real, 'power', [vx, vn])
    # Should be changed to proper test once multi-line generation is working
    # see https://github.com/sympy/sympy/issues/15824
    raises(NotImplementedError, lambda: fcode(fp1))
def _render_compile_import(funcdef, build_dir):
    code_str = render_as_source_file(funcdef, settings=dict(contract=False))
    declar = ccode(FunctionPrototype.from_FunctionDefinition(funcdef))
    return compile_link_import_strings(
        [('our_test_func.c', code_str),
         ('_our_test_func.pyx',
          ("cdef extern {declar}\n"
           "def _{fname}({typ}[:] inp, {typ}[:] out):\n"
           "    {fname}(inp.size, &inp[0], &out[0])").format(
               declar=declar, fname=funcdef.name, typ='double'))],
        build_dir=build_dir)
Exemple #6
0
def _render_compile_import(funcdef, build_dir):
    code_str = render_as_source_file(funcdef, settings=dict(contract=False))
    declar = ccode(FunctionPrototype.from_FunctionDefinition(funcdef))
    return compile_link_import_strings([
        ('our_test_func.c', code_str),
        ('_our_test_func.pyx', ("cdef extern {declar}\n"
                                "def _{fname}({typ}[:] inp, {typ}[:] out):\n"
                                "    {fname}(inp.size, &inp[0], &out[0])").format(
                                    declar=declar, fname=funcdef.name, typ='double'
                                ))
    ], build_dir=build_dir)
Exemple #7
0
def test_FunctionPrototype_and_FunctionDefinition():
    vx = Variable(x, type=real)
    vn = Variable(n, type=integer)
    fp1 = FunctionPrototype(real, 'power', [vx, vn])
    assert fp1.return_type == real
    assert fp1.name == String('power')
    assert fp1.parameters == Tuple(vx, vn)
    assert fp1 == FunctionPrototype(real, 'power', [vx, vn])
    assert fp1 != FunctionPrototype(real, 'power', [vn, vx])
    assert fp1.func(*fp1.args) == fp1

    body = [Assignment(x, x**n), Return(x)]
    fd1 = FunctionDefinition(real, 'power', [vx, vn], body)
    assert fd1.return_type == real
    assert str(fd1.name) == 'power'
    assert fd1.parameters == Tuple(vx, vn)
    assert fd1.body == CodeBlock(*body)
    assert fd1 == FunctionDefinition(real, 'power', [vx, vn], body)
    assert fd1 != FunctionDefinition(real, 'power', [vx, vn], body[::-1])
    assert fd1.func(*fd1.args) == fd1

    fp2 = FunctionPrototype.from_FunctionDefinition(fd1)
    assert fp2 == fp1

    fd2 = FunctionDefinition.from_FunctionPrototype(fp1, body)
    assert fd2 == fd1
Exemple #8
0
def test_ccode_codegen_ast():
    assert ccode(Comment("this is a comment")) == "// this is a comment"
    assert ccode(While(abs(x) > 1, [aug_assign(x, "-", 1)])) == (
        "while (fabs(x) > 1) {\n" "   x -= 1;\n" "}"
    )
    assert ccode(Scope([AddAugmentedAssignment(x, 1)])) == ("{\n" "   x += 1;\n" "}")
    inp_x = Declaration(Variable(x, type=real))
    assert ccode(FunctionPrototype(real, "pwer", [inp_x])) == "double pwer(double x)"
    assert ccode(
        FunctionDefinition(real, "pwer", [inp_x], [Assignment(x, x ** 2)])
    ) == ("double pwer(double x){\n" "   x = pow(x, 2);\n" "}")

    # Elements of CodeBlock are formatted as statements:
    block = CodeBlock(x, Print([x, y], "%d %d"), FunctionCall("pwer", [x]), Return(x),)
    assert ccode(block) == "\n".join(
        ["x;", 'printf("%d %d", x, y);', "pwer(x);", "return x;",]
    )
Exemple #9
0
def _render_compile_import(funcdef, build_dir):
    code_str = render_as_source_file(funcdef, settings=dict(contract=False))
    declar = ccode(FunctionPrototype.from_FunctionDefinition(funcdef))
    return compile_link_import_strings(
        [
            ("our_test_func.c", code_str),
            (
                "_our_test_func.pyx",
                ("#cython: language_level={}\n".format("3") +
                 "cdef extern {declar}\n"
                 "def _{fname}({typ}[:] inp, {typ}[:] out):\n"
                 "    {fname}(inp.size, &inp[0], &out[0])").format(
                     declar=declar, fname=funcdef.name, typ="double"),
            ),
        ],
        build_dir=build_dir,
    )
    def test_function():
        c_src1 = ('void fun1()' + '\n' + '{' + '\n' + 'int a;' + '\n' + '}')
        c_src2 = ('int fun2()' + '\n' + '{' + '\n' + 'int a;' + '\n' +
                  'return a;' + '\n' + '}')
        c_src3 = ('float fun3()' + '\n' + '{' + '\n' + 'float b;' + '\n' +
                  'return b;' + '\n' + '}')
        c_src4 = ('float fun4()' + '\n' + '{}')

        res1 = SymPyExpression(c_src1, 'c').return_expr()
        res2 = SymPyExpression(c_src2, 'c').return_expr()
        res3 = SymPyExpression(c_src3, 'c').return_expr()
        res4 = SymPyExpression(c_src4, 'c').return_expr()

        assert res1[0] == FunctionDefinition(
            NoneToken(),
            name=String('fun1'),
            parameters=(),
            body=CodeBlock(
                Declaration(
                    Variable(Symbol('a'),
                             type=IntBaseType(String('integer')),
                             value=Integer(0)))))

        assert res2[0] == FunctionDefinition(
            IntBaseType(String('integer')),
            name=String('fun2'),
            parameters=(),
            body=CodeBlock(
                Declaration(
                    Variable(Symbol('a'),
                             type=IntBaseType(String('integer')),
                             value=Integer(0))), Return('a')))

        assert res3[0] == FunctionDefinition(
            FloatBaseType(String('real')),
            name=String('fun3'),
            parameters=(),
            body=CodeBlock(
                Declaration(
                    Variable(Symbol('b'),
                             type=FloatBaseType(String('real')),
                             value=Float('0.0', precision=53))), Return('b')))

        assert res4[0] == FunctionPrototype(FloatBaseType(String('real')),
                                            name=String('fun4'),
                                            parameters=())
Exemple #11
0
def test_ccode_codegen_ast():
    # Note that C only allows comments of the form /* ... */, double forward
    # slash is not standard C, and some C compilers will grind to a halt upon
    # encountering them.
    assert ccode(
        Comment("this is a comment")) == "/* this is a comment */"  # not //
    assert ccode(While(abs(x) > 1,
                       [aug_assign(x, '-', 1)])) == ('while (fabs(x) > 1) {\n'
                                                     '   x -= 1;\n'
                                                     '}')
    assert ccode(Scope([AddAugmentedAssignment(x, 1)])) == ('{\n'
                                                            '   x += 1;\n'
                                                            '}')
    inp_x = Declaration(Variable(x, type=real))
    assert ccode(FunctionPrototype(real, 'pwer',
                                   [inp_x])) == 'double pwer(double x)'
    assert ccode(
        FunctionDefinition(
            real, 'pwer', [inp_x],
            [Assignment(x, x**2)])) == ('double pwer(double x){\n'
                                        '   x = pow(x, 2);\n'
                                        '}')

    # Elements of CodeBlock are formatted as statements:
    block = CodeBlock(
        x,
        Print([x, y], "%d %d"),
        FunctionCall('pwer', [x]),
        Return(x),
    )
    assert ccode(block) == '\n'.join([
        'x;',
        'printf("%d %d", x, y);',
        'pwer(x);',
        'return x;',
    ])
Exemple #12
0
        def transform_function_decl(self, node):
            """Transformation Function For Function Declaration

            Used to create nodes for function declarations and definitions for
            the respective nodes in the clang AST

            Returns
            =======

            function : Codegen AST node
                - FunctionPrototype node if function body is not present
                - FunctionDefinition node if the function body is present


            """

            if node.result_type.kind in self._data_types["int"]:
                ret_type = self._data_types["int"][node.result_type.kind]
            elif node.result_type.kind in self._data_types["float"]:
                ret_type = self._data_types["float"][node.result_type.kind]
            elif node.result_type.kind in self._data_types["bool"]:
                ret_type = self._data_types["bool"][node.result_type.kind]
            elif node.result_type.kind in self._data_types["void"]:
                ret_type = self._data_types["void"][node.result_type.kind]
            else:
                raise NotImplementedError("Only void, bool, int "
                    "and float are supported")
            body = []
            param = []
            try:
                children = node.get_children()
                child = next(children)

                # If the node has any children, the first children will be the
                # return type and namespace for the function declaration. These
                # nodes can be ignored.
                while child.kind == cin.CursorKind.NAMESPACE_REF:
                    child = next(children)

                while child.kind == cin.CursorKind.TYPE_REF:
                    child = next(children)


                # Subsequent nodes will be the parameters for the function.
                try:
                    while True:
                        decl = self.transform(child)
                        if (child.kind == cin.CursorKind.PARM_DECL):
                            param.append(decl)
                        elif (child.kind == cin.CursorKind.COMPOUND_STMT):
                            for val in decl:
                                body.append(val)
                        else:
                            body.append(decl)
                        child = next(children)
                except StopIteration:
                    pass
            except StopIteration:
                pass

            if body == []:
                function = FunctionPrototype(
                    return_type = ret_type,
                    name = node.spelling,
                    parameters = param
                )
            else:
                function = FunctionDefinition(
                    return_type = ret_type,
                    name = node.spelling,
                    parameters = param,
                    body = body
                )
            return function
Exemple #13
0
        def transform_function_decl(self, node):
            """Transformation Function For Function Declaration

            Used to create nodes for function declarations and definitions for
            the respective nodes in the clang AST

            Returns
            =======

            function : Codegen AST node
                - FunctionPrototype node if function body is not present
                - FunctionDefinition node if the function body is present


            """
            token = node.get_tokens()
            c_ret_type = next(token).spelling
            if (c_ret_type == 'void'):
                ret_type = none
            elif (c_ret_type == 'int'):
                ret_type = IntBaseType(String('integer'))
            elif (c_ret_type == 'float'):
                ret_type = FloatBaseType(String('real'))
            else:
                raise NotImplementedError("Variable not yet supported")
            body = []
            param = []
            try:
                children = node.get_children()
                child = next(children)

                # If the node has any children, the first children will be the
                # return type and namespace for the function declaration. These
                # nodes can be ignored.
                while child.kind == cin.CursorKind.NAMESPACE_REF:
                    child = next(children)

                while child.kind == cin.CursorKind.TYPE_REF:
                    child = next(children)

                # Subsequent nodes will be the parameters for the function.
                try:
                    while True:
                        decl = self.transform(child)
                        if (child.kind == cin.CursorKind.PARM_DECL):
                            param.append(decl)
                        elif (child.kind == cin.CursorKind.COMPOUND_STMT):
                            for val in decl:
                                body.append(val)
                        else:
                            body.append(decl)
                        child = next(children)
                except StopIteration:
                    pass
            except StopIteration:
                pass

            if body == []:
                function = FunctionPrototype(return_type=ret_type,
                                             name=node.spelling,
                                             parameters=param)
            else:
                function = FunctionDefinition(return_type=ret_type,
                                              name=node.spelling,
                                              parameters=param,
                                              body=body)
            return function