Example #1
0
File: ir.py Project: Delaunay/Kiwi
    def function(self, fun: Function, depth=0) -> Any:
        trace(depth, 'function')

        self.scope = self.scope.enter_scope('function')
        ftype = self.visit(fun.type, depth + 1, mode='type')

        if self.binding_name is None:
            name = self.generate_unique_binding_name()
            self.scope.insert_binding(name, fun)
        else:
            name = self.binding_name

        ir_fun = self.builder.Function(self.module, ftype=ftype, name=name)

        args = ir_fun.args

        for arg, larg in zip(fun.args, args):
            self.scope.insert_binding(arg.name, larg)

        block = ir_fun.append_basic_block(name='{}_block'.format(name))
        old = self.builder
        old_p = self.parent
        self.parent = ir_fun

        self.builder = ir.IRBuilder(block)
        self.visit(fun.body, depth + 1)

        self.builder = old
        self.parent = old_p

        self.scope = self.scope.exit_scope()
        return ir_fun
Example #2
0
    def function(self, fun: Function, depth=0) -> Any:
        trace(depth, 'function {}'.format(''))

        if len(self.bind_name) == 0:
            return self.function_lambda(fun, depth)

        return self.function_bind(self.bind_name[-1], fun, depth)
Example #3
0
File: ir.py Project: Delaunay/Kiwi
    def call(self, call: Call, depth=0) -> Any:
        trace(depth, 'call')

        lcall = self.visit(call.function, depth + 1)
        args = [self.visit(expr, depth + 1) for expr in call.args]

        if isinstance(lcall, Builtin):
            if lcall.name not in builtins:
                raise UndefinedBuiltin(lcall)

            nargs, impl = builtins[lcall.name]

            if nargs != len(call.args):
                raise ArgumentSizeMismatch(nargs, call.args)

            return impl(self.builder, args)

        # FIXME
        if isinstance(lcall, ir.LiteralStructType):
            return lcall(args)

        if isinstance(lcall, dict):
            oargs = call.args[0]
            tag, ncall = lcall[oargs.name]

            return ncall([ir.Constant(ir.IntType(32), tag)] + args)

        print(call.function, ' => ', lcall)
        print(args)

        return self.builder.call(lcall, args)
Example #4
0
File: ir.py Project: Delaunay/Kiwi
 def bind(self, bind: Bind, depth=0) -> Any:
     trace(depth, 'bind `{}`'.format(bind.name))
     name = self.binding_name
     self.binding_name = bind.name
     expr = self.visit(bind.expr, depth + 1)
     self.binding_name = name
     return Bind(bind.name, expr)
Example #5
0
    def value(self, val: Value, depth=0) -> Any:
        trace(depth, 'value')
        # print(val.value, self.b.value)

        if isinstance(val.value, Expression):
            self.b = self.b.value
            return self.visit(val.value, depth + 1)

        return val.value == self.b.value
Example #6
0
File: ir.py Project: Delaunay/Kiwi
    def arrow(self, arrow: Arrow, depth=0) -> Any:
        trace(depth, 'arrow')
        self.scope = self.scope.enter_scope('arrow')

        ftype = self.builder.FunctionType(
            self.visit(arrow.return_type, depth + 1),
            [self.visit(arg, depth + 1) for arg in arrow.args])

        self.scope = self.scope.exit_scope()
        return ftype
Example #7
0
File: ir.py Project: Delaunay/Kiwi
    def reference(self, ref: VariableRef, depth=0) -> Any:
        trace(depth, 'reference `{}`'.format(ref.name))

        # Option 1, check if this is a LLVM ref and do not visit
        v = self.scope.get_expression(ref, depth + 1)

        if isinstance(v, Expression):
            return self.visit(v, depth + 1)

        # print(v)
        return v
Example #8
0
    def arrow(self, arrow: Arrow, depth=0) -> Any:
        trace(depth, 'arrow')
        if len(arrow.args) != len(self.b.args):
            return False

        args = [
            self.type_check(a, b, depth + 1)
            for a, b in zip(arrow.args, self.b.args)
        ]

        return self.type_check(arrow.return_type, self.b.return_type, depth + 1) \
               and reduce(lambda x, y: x and y, args, True)
Example #9
0
File: ir.py Project: Delaunay/Kiwi
    def builtin(self, builtin: Builtin, depth=0) -> Any:
        trace(depth, 'builtin')

        if builtin.name not in builtins:
            raise UndefinedBuiltin(builtin)

        nargs, impl = builtins[builtin.name]

        if self.mode == 'type':
            return impl

        return builtin
Example #10
0
    def call(self, call: Call, depth=0) -> Any:
        trace(depth, 'call')
        fun = self.visit(call.function, depth + 1)

        args = []
        for arg in call.args:
            arg_val = self.visit(arg, depth + 1)
            if isinstance(arg, NamedArgument):
                args.append('{} = {}'.format(arg.name, arg_val))
            else:
                args.append(arg_val)

        args = ', '.join(args)
        return '{}({})'.format(fun, args)
Example #11
0
    def struct(self, struct: Struct, depth=0) -> Any:
        trace(depth, 'struct')
        if not self.structural_check:
            return struct is self.b

        if len(struct.members) != len(self.b.members):
            return False

        args = [
            self.type_check(a.type, b.type, depth + 1) and a.name == b.name
            for a, b in zip(struct.members, self.b.members)
        ]

        return reduce(lambda x, y: x and y, args, True)
Example #12
0
File: ir.py Project: Delaunay/Kiwi
    def block(self, block: Block, depth=0) -> Any:
        trace(depth, 'block')
        blk = ir.Block(self.parent)

        old = self.builder
        old_p = self.parent
        self.builder = ir.IRBuilder(block)

        for expr in block.expressions:
            self.visit(expr, depth + 1)

        self.builder = old
        self.parent = old_p
        return blk
Example #13
0
 def arrow(self, arrow: Arrow, depth=0) -> Any:
     trace(depth, 'arrow')
     args = ', '.join([self.visit(arg, depth + 1) for arg in arrow.args])
     return '({}) -> {}'.format(args,
                                self.visit(arrow.return_type, depth + 1))