Ejemplo n.º 1
0
    def build_or_get_function(self, parent, volpe_args):
        module: ir.Module = parent.builder.module

        func_args = unwrap(self.args())
        if not isinstance(volpe_args, VolpeObject):
            func_args = ir.LiteralStructType([func_args])

        for func in module.functions:
            if func.name == self.name:
                break
        else:
            func_type = ir.FunctionType(unwrap(self.ret()), func_args)
            func = ir.Function(module, func_type, self.name)

        volpe_func_type = ir.FunctionType(unwrap(
            self.ret()), [ir.LiteralStructType([]),
                          unwrap(self.args())])
        volpe_func = ir.Function(module, volpe_func_type,
                                 str(next(module.func_count)))
        with build_func(volpe_func) as (b, args):
            b: ir.IRBuilder
            args = [args[1]]
            if isinstance(volpe_args, VolpeObject):
                args = [
                    b.extract_value(args[0], i)
                    for i in range(len(volpe_args.type_dict))
                ]

            b.ret(b.call(func, args))

        return volpe_func
Ejemplo n.º 2
0
    def build_or_get_function(self, parent, args):
        inst = self.tree.instances[args]
        if not hasattr(inst, "func"):
            arg_type = inst.children[0].return_type
            ret_type = inst.children[1].return_type

            module = parent.builder.module
            func_name = str(next(module.func_count))
            func_type = ir.FunctionType(
                unwrap(ret_type),
                [unwrap(self), unwrap(arg_type)])
            inst.func = ir.Function(module, func_type, func_name)

            with build_func(inst.func) as (b, args):
                b: ir.IRBuilder
                with options(b, args[1].type) as (rec, phi):
                    rec(args[1])

                new_values = [
                    b.extract_value(args[0], i) for i in range(len(self.env))
                ]
                env_scope = dict(zip(self.env.keys(), new_values))
                env_scope["@"] = args[0]

                def scope(name):
                    return env_scope[name]

                parent.__class__(b, inst.children[1], scope, b.ret, rec,
                                 (inst.children[0], phi))

        return inst.func
Ejemplo n.º 3
0
def build_main(module, run_func, printf_func):
    main_func = ir.Function(
        module, ir.FunctionType(int32,
                                [int32, char.as_pointer().as_pointer()]),
        "main")
    with build_func(main_func) as (b, args):
        num_args = b.zext(args[0], int64)
        closure = b.call(run_func, [])
        func = b.extract_value(closure, 0)
        env_ptr = b.extract_value(closure, 3)

        pointer = b.call(module.malloc, [b.mul(num_args, size(string_type))])
        pointer = b.bitcast(pointer, string_type.unwrap().as_pointer())

        with options(b, int64) as (ret, phi):
            ret(int64(0))

        with b.if_then(b.icmp_unsigned("<", phi, num_args)):
            string = b.load(b.gep(args[1], [phi]))
            new_string = string_to_volpe(b, string)
            b.store(new_string, b.gep(pointer, [phi]))

            ret(b.add(phi, int64(1)))

        arguments = string_array.unwrap()(ir.Undefined)
        arguments = b.insert_value(arguments, pointer, 0)
        arguments = b.insert_value(arguments, num_args, 1)

        arg_obj = string_obj.unwrap()(ir.Undefined)
        arg_obj = b.insert_value(arg_obj, arguments, 0)

        res = b.call(func, [env_ptr, arg_obj])
        free(b, closure)

        print_obj = VolpeObject({"_0": string_type}).unwrap()(ir.Undefined)
        print_obj = b.insert_value(print_obj, res, 0)
        b.call(b.extract_value(printf_func, 0),
               [pint8(ir.Undefined), print_obj])

        b.ret(int32(0))
Ejemplo n.º 4
0
def volpe_llvm(tree: TypeTree,
               verbose=False,
               more_verbose=False,
               console=False):
    if more_verbose:
        print(tree.pretty())

    arg_scope = {}

    def scope(name, local_tree: TypeTree):
        if name in arg_scope:
            return arg_scope[name]
        raise VolpeError(f"variable `{name}` not found", local_tree)

    AnnotateScope(tree, scope)

    if verbose:
        print(tree.pretty())

    module = ir.Module("program")
    module.func_count = itertools.count()

    run_func = ir.Function(
        module,
        ir.FunctionType(unknown, [unwrap(tree.return_type).as_pointer()]),
        "run")
    with build_func(run_func) as (b, args):
        arg_scope = {}

        def scope(name):
            return arg_scope[name]

        def ret(value):
            b.store(value, args[0], 8)
            b.ret_void()

        LLVMScope(b, tree, scope, ret, None)

    return str(module)