# Path: cbl/native_type.py
# class NativeType:
# 
#     def __repr__(self):
#         return self.__class__.__name__
# 
#     def instantiate(self, compiler, args):
#         assert not args, "%s does not take arguments" % self
#         return self
# 
#     @property
#     def typename(self):
#         return self.__typename
# 
#     @typename.setter
#     def typename(self, name):
#         self.__typename = name
#         meta = self.metatype
#         if meta is not None:
#             meta.typename = name + '--meta'
# 
#     def allocate(self, compiler, namehint):
#         assert False, "%s is not allocatable" % self.typename
# 
#     @property
#     def metatype(self):
#         return None
# 
#     @property
#     def ir_type(self):
#         raise TypeError('%s does not have an IR type' % self)
# 
#     def get_property(self, compiler, container, prop):
#         raise TypeError('Unknown property %s on %s' % (prop, self))
# 
#     def dispatch_operator(self, compiler, op, left, right=None):
#         if op in ASSIGN_OP:
#             # Remove '=' from op
#             return self._assign_op(compiler, op[:-1], left, right)
#         raise TypeError('Invalid operation "%s" on %s' % (op, self))
# 
#     def _assign_op(self, compiler, op, left, right):
#         tmp = self.dispatch_operator(compiler, op, left, right)
#         return self.dispatch_operator(compiler, '=', left, tmp)
# 
#     def ir_types(self):
#         return (self.ir_type,)
# 
#     def as_variables(self, instance):
#         return (self.as_variable(instance),)
# 
#     def as_variable(self, instance):
#         raise TypeError('%s cannot be converted to a variable' % self)
# 
#     def as_ir_variable(self, instance):
#         return self.as_variable(instance)
# 
#     # Convert a sequence of variables (e.g. from as_variables()) back into
#     # Our high-level value
#     def from_variables(self, compiler, vars):
#         it = iter(vars)
# 
#         # The default implementation is to call allocate but provide variables
#         # via the pool of yet-to-consume variables
#         def shift_var(subname, var_type):
#             var = next(it)
#             # verify IR type is consistent
#             assert var.type == var_type
#             return var
# 
#         with compiler.set_create_var(shift_var):
#             value = self.allocate(compiler, 'restored')
#             # Check we consumed all the variables
#             assert all(False for _ in it)
#             return value
# 
#     def effective_var_size(self):
#         if self.ir_type:
#             return 1
#         assert False
# 
#     def run_constructor(self, compiler, container, arguments):
#         assert not arguments, (self, arguments)
# 
#     def do_construction(self, compiler, instance, member_inits):
#         assert not member_inits
# 
#     def coerce_to(self, compiler, container, type):
#         if type == self:
#             return container
#         return None
# 
# Path: cbl/containers.py
# class DelegatedWrite:
# 
#     def write(self, compiler, other):
#         assert False


from collections import namedtuple
from .native_type import NativeType
from .containers import DelegatedWrite
import cmd_ir.instructions as i
        return i.VarType.nbt

    def allocate(self, compiler, namehint):
        return compiler.create_var(namehint, self.ir_type)

    def as_variable(self, instance):
        return instance

    def run_constructor(self, compiler, instance, arguments):
        assert len(arguments) <= self.size
        compiler.array_support.allocate(self.size)
        var = instance.value
        array = compiler.insn_def(i.CreateNBTList(self.nbt_type))
        init_val = self._init_val(compiler)
        with compiler.compiletime():
            for _ in range(self.size):
                compiler.add_insn(i.NBTListAppend(array, init_val))
        compiler.add_insn(i.NBTAssign(var, array))
        for n, arg in enumerate(arguments):
            compiler.array_support.set(var, n, arg.type.as_variable(arg.value))

    def _init_val(self, compiler):
        # TODO non-int defaults
        return compiler.insn_def(i.CreateNBTValue(self.nbt_type, 0))

    def dispatch_operator(self, compiler, op, left, right=None):
        if op == '[]':
            return ArrayElementHolder(compiler, self, left, right)
        return super().dispatch_operator(compiler, op, left, right)


# Path: cbl/native_type.py
# class NativeType:
# 
#     def __repr__(self):
#         return self.__class__.__name__
# 
#     def instantiate(self, compiler, args):
#         assert not args, "%s does not take arguments" % self
#         return self
# 
#     @property
#     def typename(self):
#         return self.__typename
# 
#     @typename.setter
#     def typename(self, name):
#         self.__typename = name
#         meta = self.metatype
#         if meta is not None:
#             meta.typename = name + '--meta'
# 
#     def allocate(self, compiler, namehint):
#         assert False, "%s is not allocatable" % self.typename
# 
#     @property
#     def metatype(self):
#         return None
# 
#     @property
#     def ir_type(self):
#         raise TypeError('%s does not have an IR type' % self)
# 
#     def get_property(self, compiler, container, prop):
#         raise TypeError('Unknown property %s on %s' % (prop, self))
# 
#     def dispatch_operator(self, compiler, op, left, right=None):
#         if op in ASSIGN_OP:
#             # Remove '=' from op
#             return self._assign_op(compiler, op[:-1], left, right)
#         raise TypeError('Invalid operation "%s" on %s' % (op, self))
# 
#     def _assign_op(self, compiler, op, left, right):
#         tmp = self.dispatch_operator(compiler, op, left, right)
#         return self.dispatch_operator(compiler, '=', left, tmp)
# 
#     def ir_types(self):
#         return (self.ir_type,)
# 
#     def as_variables(self, instance):
#         return (self.as_variable(instance),)
# 
#     def as_variable(self, instance):
#         raise TypeError('%s cannot be converted to a variable' % self)
# 
#     def as_ir_variable(self, instance):
#         return self.as_variable(instance)
# 
#     # Convert a sequence of variables (e.g. from as_variables()) back into
#     # Our high-level value
#     def from_variables(self, compiler, vars):
#         it = iter(vars)
# 
#         # The default implementation is to call allocate but provide variables
#         # via the pool of yet-to-consume variables
#         def shift_var(subname, var_type):
#             var = next(it)
#             # verify IR type is consistent
#             assert var.type == var_type
#             return var
# 
#         with compiler.set_create_var(shift_var):
#             value = self.allocate(compiler, 'restored')
#             # Check we consumed all the variables
#             assert all(False for _ in it)
#             return value
# 
#     def effective_var_size(self):
#         if self.ir_type:
#             return 1
#         assert False
# 
#     def run_constructor(self, compiler, container, arguments):
#         assert not arguments, (self, arguments)
# 
#     def do_construction(self, compiler, instance, member_inits):
#         assert not member_inits
# 
#     def coerce_to(self, compiler, container, type):
#         if type == self:
#             return container
#         return None
# 
# Path: cbl/containers.py
# class DelegatedWrite:
# 
#     def write(self, compiler, other):
#         assert False


# Path: cbl/array_support.py
from collections import namedtuple
from .native_type import NativeType
from .containers import DelegatedWrite
import cmd_ir.instructions as i

        return i.VarType.nbt

    def allocate(self, compiler, namehint):
        return compiler.create_var(namehint, self.ir_type)

    def as_variable(self, instance):
        return instance

    def run_constructor(self, compiler, instance, arguments):
        assert len(arguments) <= self.size
        compiler.array_support.allocate(self.size)
        var = instance.value
        array = compiler.insn_def(i.CreateNBTList(self.nbt_type))
        init_val = self._init_val(compiler)
        with compiler.compiletime():
            for _ in range(self.size):
                compiler.add_insn(i.NBTListAppend(array, init_val))
        compiler.add_insn(i.NBTAssign(var, array))
        for n, arg in enumerate(arguments):
            compiler.array_support.set(var, n, arg.type.as_variable(arg.value))

    def _init_val(self, compiler):
        # TODO non-int defaults
        return compiler.insn_def(i.CreateNBTValue(self.nbt_type, 0))

    def dispatch_operator(self, compiler, op, left, right=None):
        if op == '[]':
            return ArrayElementHolder(compiler, self, left, right)
        return super().dispatch_operator(compiler, op, left, right)


class ArrayElementHolder(DelegatedWrite):