# Path: cbl/containers.py
# class AsyncReturn:
# class DelegatedWrite:
#     def __init__(self, realret, callback):
#     def must_await(self):
#     def type(self):
#     def value(self):
#     def write(self, compiler, other):
# 
# 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
# 
# class MetaType(NativeType):
# 
#     def __init__(self, the_type):
#         self.the_type = the_type
# 
#     def call_constructor(self, compiler, container, args):
#         the_type = container.type.the_type
#         obj = the_type.allocate(compiler, safe_typename(the_type) + '_inst')
#         tmp = Temporary(the_type, obj)
#         the_type.run_constructor(compiler, tmp, args)
#         return tmp
# 
# Path: cmd_ir/reader.py
# class Reader:
# 
#     def __init__(self):
#         self.parser = lark_parser()
#         self.env = []
# 
#     def set_env(self, name, value):
#         self.env.append((name, value))
# 
#     def read(self, text):
#         tree = self.parser.parse(text)
#         builder = BuildProgram()
#         self.preprocess(builder.top)
#         builder.visit(tree)
#         builder.top.end()
#         return builder.top
# 
#     def preprocess(self, top):
#         for name, value in self.env:
#             top.store(name, value)
# 
#     def read_blocks(self, func, blocks):
#         tree = self.parser.parse('%HOOK BLOCKS ' + blocks)
#         builder = BuildProgram()
#         builder.func = func
#         builder.holder = func
#         # Return blocks in order of occurence
#         return builder.visit(tree)
# 
#     def read_instruction(self, func, insn, moreargs=()):
#         tree = self.parser.parse('%HOOK INSN ' + insn)
#         builder = BuildProgram()
#         builder.func = func
#         builder.holder = func
#         builder._hook_more_args = moreargs
#         # the "start" visitor returns a list with one element - the insn
#         return builder.visit(tree)[0]


from .containers import LiteralString, Temporary
from .native_type import NativeType, MetaType
from cmd_ir.reader import Reader
import cmd_ir.instructions as i


_READER_ = Reader()

class IRTypeInstance:

    def __init__(self, name):
        self._name = name
        self.var = None

    def ctor(self, compiler, insn_str, moreargs):
        insn = _READER_.read_instruction(compiler.func, insn_str, moreargs)
        self.var = compiler.define(self._name, insn)

    def __repr__(self):
        return 'IRTypeInstance(%s)' % self.var


# Path: cbl/containers.py
# class AsyncReturn:
# class DelegatedWrite:
#     def __init__(self, realret, callback):
#     def must_await(self):
#     def type(self):
#     def value(self):
#     def write(self, compiler, other):
# 
# 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
# 
# class MetaType(NativeType):
# 
#     def __init__(self, the_type):
#         self.the_type = the_type
# 
#     def call_constructor(self, compiler, container, args):
#         the_type = container.type.the_type
#         obj = the_type.allocate(compiler, safe_typename(the_type) + '_inst')
#         tmp = Temporary(the_type, obj)
#         the_type.run_constructor(compiler, tmp, args)
#         return tmp
# 
# Path: cmd_ir/reader.py
# class Reader:
# 
#     def __init__(self):
#         self.parser = lark_parser()
#         self.env = []
# 
#     def set_env(self, name, value):
#         self.env.append((name, value))
# 
#     def read(self, text):
#         tree = self.parser.parse(text)
#         builder = BuildProgram()
#         self.preprocess(builder.top)
#         builder.visit(tree)
#         builder.top.end()
#         return builder.top
# 
#     def preprocess(self, top):
#         for name, value in self.env:
#             top.store(name, value)
# 
#     def read_blocks(self, func, blocks):
#         tree = self.parser.parse('%HOOK BLOCKS ' + blocks)
#         builder = BuildProgram()
#         builder.func = func
#         builder.holder = func
#         # Return blocks in order of occurence
#         return builder.visit(tree)
# 
#     def read_instruction(self, func, insn, moreargs=()):
#         tree = self.parser.parse('%HOOK INSN ' + insn)
#         builder = BuildProgram()
#         builder.func = func
#         builder.holder = func
#         builder._hook_more_args = moreargs
#         # the "start" visitor returns a list with one element - the insn
#         return builder.visit(tree)[0]


# Path: cbl/ir_type.py
from .containers import LiteralString, Temporary
from .native_type import NativeType, MetaType
from cmd_ir.reader import Reader
import cmd_ir.instructions as i



_READER_ = Reader()

class IRTypeInstance:

    def __init__(self, name):
        self._name = name
        self.var = None

    def ctor(self, compiler, insn_str, moreargs):
        insn = _READER_.read_instruction(compiler.func, insn_str, moreargs)
        self.var = compiler.define(self._name, insn)

    def __repr__(self):
        return 'IRTypeInstance(%s)' % self.var


class IRType(NativeType):