Ejemplo n.º 1
0
    def test_run(self):
        from nitrous.module import jit_module, so_module
        from nitrous.function import function, c_function
        from nitrous.types import Float

        axpy = c_function("axpy", Float, [Float, Float, Float])
        multiply = c_function("multiply", Float, [Float, Float])

        @function(Float, a=Float, b=Float, c=Float)
        def foo(a, b, c):
            return axpy(a, b, c) + multiply(a, c)

        a, b, c = 11, 23, 7
        ref = (a * b + c) + a * c

        jit_m = jit_module([foo], libs=[self.lib])
        self.assertEqual(jit_m.foo(a, b, c), ref)

        so_m = so_module([foo], libs=[self.lib])
        self.assertEqual(so_m.foo(a, b, c), ref)
Ejemplo n.º 2
0
    def test_run(self):
        from nitrous.module import jit_module, so_module
        from nitrous.function import function, c_function
        from nitrous.types import Float

        axpy = c_function("axpy", Float, [Float, Float, Float])
        multiply = c_function("multiply", Float, [Float, Float])

        @function(Float, a=Float, b=Float, c=Float)
        def foo(a, b, c):
            return axpy(a, b, c) + multiply(a, c)

        a, b, c = 11, 23, 7
        ref = (a * b + c) + a * c

        jit_m = jit_module([foo], libs=[self.lib])
        self.assertEqual(jit_m.foo(a, b, c), ref)

        so_m = so_module([foo], libs=[self.lib])
        self.assertEqual(so_m.foo(a, b, c), ref)
Ejemplo n.º 3
0
def print_(*args, **kwargs):
    """``print_(value, ..., end='\\n', file=sys.stdout)``

    Also available through ``print`` built-in.

    Currently supports only several basic types, namely strings, integers of
    different widths, floats and doubles. *file* argument accepts only file
    objects with ``fileno()`` method. *sep* argument is currently unsupported.

    """
    from nitrous.function import c_function, _get_or_create_function, emit_constant_string
    from nitrous.types import Int, Long, Double, String
    from sys import stdout

    # TODO add support for .sep parameter; this will require
    # to implement string joining or have one printf for every arg.

    # Move this somewhere, maybe `nitrous.lib.c`?
    dprintf = c_function("dprintf", Int, [Int, String])

    def emit(builder):

        module = llvm.GetParentModule__(builder)
        llvm_printf, _ = _get_or_create_function(module, dprintf, vargs=True)

        cast_args = []
        formats = []

        # Getting file descriptor
        file_ = kwargs['file'] or stdout
        fileno = llvm.ConstInt(Int.llvm_type, file_.fileno(), True)

        # Performing certain casts for simplicity.
        for a in args:
            ty = llvm.TypeOf(a)
            if llvm.types_equal(ty, String.llvm_type):
                formats.append("%s")
            elif llvm.GetTypeKind(ty) == llvm.IntegerTypeKind:
                formats.append("%ld")
                a, _ = cast(a, Long).emit(builder)
            elif llvm.GetTypeKind(ty) == llvm.DoubleTypeKind:
                formats.append("%lf")
            elif llvm.GetTypeKind(ty) == llvm.FloatTypeKind:
                formats.append("%lf")
                # XXX for some reason floats are not printing. Looking
                # at Clang disassembly of printf("%f", (float)2.0), the
                # resulting constant type is double... Why?
                a, _ = cast(a, Double).emit(builder)
            else:
                raise TypeError("Unknown argument type")

            cast_args.append(a)

        # Appending end terminator, if any, else a newline.
        end = kwargs['end']
        if end is None:
            end = emit_constant_string(builder, "\n")

        cast_args.append(end)

        # Creating final format string, args and making the call.
        format_ = emit_constant_string(builder, " ".join(formats) + "%s")
        args_ = (llvm.ValueRef * (len(cast_args) + 2))(fileno, format_,
                                                       *cast_args)

        llvm.BuildCall(builder, llvm_printf, args_, len(args_), "print")

        return None, None

    return ValueEmitter(emit)
Ejemplo n.º 4
0
def print_(*args, **kwargs):
    """``print_(value, ..., end='\\n', file=sys.stdout)``

    Also available through ``print`` built-in.

    Currently supports only several basic types, namely strings, integers of
    different widths, floats and doubles. *file* argument accepts only file
    objects with ``fileno()`` method. *sep* argument is currently unsupported.

    """
    from nitrous.function import c_function, _get_or_create_function, emit_constant_string
    from nitrous.types import Int, Long, Double, String
    from sys import stdout

    # TODO add support for .sep parameter; this will require
    # to implement string joining or have one printf for every arg.

    # Move this somewhere, maybe `nitrous.lib.c`?
    dprintf = c_function("dprintf", Int, [Int, String])

    def emit(builder):

        module = llvm.GetParentModule__(builder)
        llvm_printf, _ = _get_or_create_function(module, dprintf, vargs=True)

        cast_args = []
        formats = []

        # Getting file descriptor
        file_ = kwargs['file'] or stdout
        fileno = llvm.ConstInt(Int.llvm_type, file_.fileno(), True)

        # Performing certain casts for simplicity.
        for a in args:
            ty = llvm.TypeOf(a)
            if llvm.types_equal(ty, String.llvm_type):
                formats.append("%s")
            elif llvm.GetTypeKind(ty) == llvm.IntegerTypeKind:
                formats.append("%ld")
                a, _ = cast(a, Long).emit(builder)
            elif llvm.GetTypeKind(ty) == llvm.DoubleTypeKind:
                formats.append("%lf")
            elif llvm.GetTypeKind(ty) == llvm.FloatTypeKind:
                formats.append("%lf")
                # XXX for some reason floats are not printing. Looking
                # at Clang disassembly of printf("%f", (float)2.0), the
                # resulting constant type is double... Why?
                a, _ = cast(a, Double).emit(builder)
            else:
                raise TypeError("Unknown argument type")

            cast_args.append(a)

        # Appending end terminator, if any, else a newline.
        end = kwargs['end']
        if end is None:
            end = emit_constant_string(builder, "\n")

        cast_args.append(end)

        # Creating final format string, args and making the call.
        format_ = emit_constant_string(builder, " ".join(formats) + "%s")
        args_ = (llvm.ValueRef * (len(cast_args) + 2))(fileno, format_, *cast_args)

        llvm.BuildCall(builder, llvm_printf, args_, len(args_), "print")

        return None, None

    return ValueEmitter(emit)