def get_subclasses(cls):
def type_check(in_arg, arg_type, arg_name, insn):
    def __init__(self, name):
    def __get__(self, instance, owner):
    def __set__(self, instance, value):
    def __init__(self, name, bases, dct):
    def lookup(cls, name):
    def __init__(self, *args):
    def __str__(self):
    def validate(self):
    def declare(self):
    def activate(self, seq):
    def apply(self, out, func):
    def run(self, ev):
    def serialize_args(self, holder):
        def serialize(val):
    def serialize(self, holder):
    def query(self, argtype):
    def changed(self, name):
    def copy(self):
    def copy_with_changes(self, mapping):
    def terminator(self):
    def single_command(self):
    def as_single_cmd(self, func):
    def namespace(self):
def _get_if_single_cmd(insn, func):
    def __init__(self):
    def prepend(self, cmd):
    def last(self, cmd):
    def write(self, cmd):
    def allocate_temp(self):
    def free_temp(self, tmp):
    def __init__(self, insn, name, argtype, access):
    def name(self):
    def access(self):
    def val(self):
    def val(self, value):
    def accepts(self, vtype):
    def apply(self, out, func):
    def run(self, ev):
    def activate(self, seq):
    def preapply(self, preamble):
    def postapply(self, out, func):
    def declare(self):
    def activate(self, seq):
    def apply(self, out, func):
    def activate(self, seq):
    def run(self, ev):
    def activate(self, seq):
    def preapply(self, preamble):
    def construct(self):
    def copy(self):
    def serialize(self, holder):
    def single_command(self):
    def apply(self, out, func):
    def as_single_cmd(self, func):
    def get_cmd(self, func):
    def __init__(self, insn, name, t_index, argtype, access):
    def val(self):
    def val(self, value):
    def accepts(self, vtype):
    def __init__(self):
    def context(self, ctx):
    def close(self):
    def copy_with_changes(self, mapping):
    def query(self, argtype):
READ, WRITE = 'acc_read', 'acc_write'
STACK_HEAD = -1
class InsnArgProperty:
class InsnMeta(abc.ABCMeta):
class Insn(metaclass=InsnMeta):
class _MockFunction:
class _NotASingleCommandError(Exception):
class _SingleCommandWriter:
class QueryResult:
class PreambleInsn(Insn, metaclass=abc.ABCMeta):
class CompileTimeInsn(Insn):
class RuntimeInsn(Insn):
class RunAndCompileInsn(Insn):
class ConstructorInsn(PreambleInsn, metaclass=abc.ABCMeta):
class SingleCommandInsn(RuntimeInsn, metaclass=abc.ABCMeta):
class TupleQueryResult(QueryResult):
class MultiOpen:
class RuntimeHeldInsn(RuntimeInsn): class FuncWriter(metaclass=abc.ABCMeta):
class CmdWriter:
class TemporaryVarGen:
class InstructionSeq:
class Preamble(InstructionSeq):
class Scope(OrderedDict):
class VariableHolder:
class Pragma(metaclass=abc.ABCMeta):
class TopLevel(VariableHolder):
class VisibleFunction(FunctionLike):
class ExternCommon(VisibleFunction):
class ExternFunction(ExternCommon):
class DynLinkFunction(ExternCommon):
class IRFunction(VisibleFunction, VariableHolder):
class BasicBlock(FunctionLike, InstructionSeq):
class SuperBlock(BasicBlock):
class Evaluator:
class CompileTimeFunction(VariableHolder):
class CompileTimeBlock(BasicBlock):
class ObjectFormat:
    def namespace(self):
    def write_func_table(self, table):
    def write_function(self, name, insns):
    def write_event_handler(self, handler, event):
    def write_setup_function(self, func):
    def write_bossbar(self, name, display):
    def write_team(self, name, display):
    def write_objective(self, name, criteria):
    def write_extern_vars(self, names):
    def write_global_nbt(self, storage, path, init_val):
    def __init__(self, func_writer, temp_gen):
    def namespace(self):
    def prepend(self, cmd):
    def last(self, cmd):
    def write(self, cmd):
    def get_output(self):
    def allocate_temp(self):
    def free_temp(self, tmp):
    def __init__(self, writer):
    def next(self):
    def free(self, temp):
    def finish(self):
    def __init__(self, holder):
    def validate_insn(self, insn):
    def add(self, insn, with_name=False, namehint=None):
    def define(self, insn):
    def is_empty(self):
    def apply_mapping(self, arg_type, mapping):
    def transform(self, func):
    def __init__(self, parent):
    def validate_insn(self, insn):
    def apply(self, writer):
    def serialize(self):
    def __str__(self):
    def __init__(self, parent=None):
    def __setitem__(self, key, value):
    def __missing__(self, key):
    def __contains__(self, key):
    def get_or_create(self, name, callback):
    def get_no_parent(self, key):
    def contains_no_parent(self, key):
    def for_value(self, value, look_parent=True):
    def __repr__(self):
    def isolate(self):
    def uniq_name(self, hint):
    def uniq(self, hint, callback):
    def generate_name(self, namehint, value):
    def store(self, name, value):
    def name_for(self, value):
    def get_var(self, name):
    def lookup(self, name):
    def transform_scope(self, func):
    def reset_var_usage(self):
    def reduce(self, acc, val):
    def apply(self, top, value):
    def __init__(self):
    def get_or_create_func(self, name):
    def create_function(self, namehint):
    def _create_func(self, name):
    def define_function(self, name):
    def create_global(self, namehint, vartype, is_extern=False, ns=None):
    def lookup_func(self, name):
    def include_from(self, other):
    def end(self):
    def writeout(self, writer):
    def get_extern_symbol_table(self, session):
    def serialize(self):
    def linker(*tops):
    def run_pragmas(self, known_pragmas):
    def finished(self):
    def expect_signature(self, other):
    def get_func_table(self):
    def writeout(self, writer, temp_gen):
    def validate_args(self, args, retvars):
    def extern_visibility(self):
    def __init__(self, global_name, params=None, returns=None):
    def finished(self):
    def expect_signature(self, other):
    def extern_visibility(self):
    def is_inline(self):
    def usage(self):
    def is_empty(self):
    def serialize(self):
    def __init__(self, name, params=None, returns=None):
    def writeout(self, writer, temp_gen):
    def global_name(self):
    def get_func_table(self):
    def is_pure(self):
    def __str__(self):
    def __init__(self, name, params, returns, pure):
    def writeout(self, writer, temp_gen):
    def global_name(self):
    def get_func_table(self):
    def is_pure(self):
    def __str__(self):
    def __init__(self, name, top):
    def _create_super_block(self, name):
    def usage(self):
    def set_namespace(self, ns):
    def _set_namespace(self, ns):
    def add_parameter(self, vtype, passtype):
    def add_return(self, vtype):
    def create_compiletime(self):
    def get_compiletimes(self):
    def entry_point_usage(self):
    def has_usage(self):
    def reset(self):
    def is_empty(self):
    def set_extern(self, is_extern):
    def extern_visibility(self):
    def is_pure(self):
    def set_pure(self):
    def is_inline(self):
    def set_inline(self):
    def is_defined(self):
    def finished(self):
    def finalized(self):
    def is_internal(self):
    def global_name(self):
    def blocks(self):
    def allblocks(self):
    def get_or_create_block(self, name):
    def _create_block(self, name):
    def create_block(self, namehint):
    def create_var(self, namehint, vartype):
    def expect_signature(self, other):
    def end(self):
    def get_func_table(self):
    def writeout(self, writer, temp_gen):
    def get_registers(self):
    def is_closed(self):
    def _inline_seq(self, from_seq, to_seq, scope_mapping):
    def inline_into(self, other, args, retvars):
    def configure_parameters(self, hasownstackframe):
    def variables_finalized(self):
    def add_entry_exit(self):
    def add_advancement_revoke(self, event):
    def serialize(self):
    def __str__(self):
    def __init__(self, name, func):
    def usage(self):
    def reset(self):
    def use_count(self):
    def set_is_function(self):
    def copy_to(self, func):
    def global_name(self):
    def __str__(self):
    def end(self):
    def is_terminated(self):
    def validate_insn(self, insn):
    def writeout(self, func_writer, temp_gen):
    def serialize(self, indent=4):
    def __init__(self, name, func):
    def global_name(self):
    def usage(self):
    def use_count(self):
    def superclear(self):
    def is_empty(self):
    def reset(self):
    def __init__(self, entry):
    def jump(self, block):
    def fork_jump(self, block):
    def run(self):
    def stop(self):
    def __init__(self, real_func):
    def store(self, name, value):
    def preamble(self):
    def create_compiletime(self):
    def get_or_create_block(self, name):
    def _create_block(self, name):
    def create_block(self, namehint):
    def create_var(self, namehint, vartype):
    def run_and_return(self):
    def serialize(self):
    def validate_insn(self, insn):
    def global_name(self):
    def __str__(self):
    def __init__(self, top):
    def load(data):
    def save(top):
    VERSION = "1.0.0" def Opt(optype):
    return (type(None), optype) class Variable(NativeType, metaclass=abc.ABCMeta):

    def __init__(self, vartype):
        assert isinstance(vartype, VarType)
        self.type = vartype
        self.__use_w = 0
        self.__use_r = 0

    @property
    @abc.abstractmethod
    def namespace(self):
        pass

    def __repr__(self):
        return '%s(%s)' % (self.__class__.__name__, self.type)

    def open_for_write(self, out, read=False):
        return OpenVar(self, out, read=read, write=True)

    def open_for_read(self, out):
        return OpenVar(self, out)

    def usage_read(self):
        self.__use_r += 1

    def usage_write(self):
        self.__use_w += 1

    def reset_usage(self):
        self.__use_w = 0
        self.__use_r = 0

    @property
    def is_read_from(self):
        return self.__use_r > 0

    @property
    def is_written_to(self):
        return self.__use_w > 0

    @property
    def is_referenced(self):
        return self.is_read_from or self.is_written_to

    @property
    def is_entity_local(self):
        # Bit of a hack
        return isinstance(self, EntityLocalVariable)

    @abc.abstractmethod
    def read(self):
        """
        Returns a command that sets the "result" to this variable's
        value. The value is left unscaled as an int.
        """
        pass

    def clone_to(self, other, out):
        assert other.type == self.type, "TODO"
        ref = other._direct_ref()
        # Need to adjust for scaling
        if ref is not None:
            self._write_to_reference(ref, out)
        else:
            other._store_from_cmd(self.read(), out)

    @abc.abstractmethod
    def set_const_val(self, value, out):
        pass

    def to_int(self, value):
        return self.type.to_int(value)

    def scale_down(self, ref, out):
        if self.type.scale != 1:
            # TODO extract to constant reference
            scaleparam = out.allocate_temp()
            out.write(c.SetConst(scaleparam, self.type.scale))
            out.write(c.OpDiv(ref, scaleparam))
            out.free_temp(scaleparam)

    def scale_other_to_this(self, other, otherref, out):
        factor = self.type.scale / other.type.scale
        op = c.OpMul
        if factor < 1:
            factor = 1 / factor
            op = c.OpDiv
        factor = int(factor)
        if factor == 1:
            return otherref, False
        scaled = out.allocate_temp()
        out.write(c.OpAssign(scaled, otherref))
        # TODO extract to constant reference
        scaleparam = out.allocate_temp()
        out.write(c.SetConst(scaleparam, factor))
        out.write(op(scaled, scaleparam))
        out.free_temp(scaleparam)
        return scaled, True

    def push_to_stack(self, out):
        self.as_nbt_variable(out).push_to_stack(out)

    def as_nbt_variable(self, out):
        # Create a virtual variable to store the value as NBT
        var = WorkingNbtVariable(self.type, self.namespace)
        self.clone_to(var, out)
        return var

    def realign_frame(self, shift):
        pass

    ## DIRECT ACCESS

    def _direct_ref(self):
        return None

    def _direct_nbt(self):
        return None

    ## INTERNAL ONLY

    def _write_to_reference(self, ref, out):
        out.write(c.ExecuteChain()
                  .store('result')
                  .score(ref)
                  .run(self.read()))

    def _read_from_reference(self, ref, out):
        self._store_from_cmd(c.GetValue(ref), out)

    @abc.abstractmethod
    def _store_from_cmd(self, cmd, out):
        """
        Store command "result" value into this variable.
        Result is not scaled therefore must be scaled as appropriate.
        """
        pass class VarType(InsnArg):

    __LOOKUP = {}

    def __init__(self, name, nbt_key, numeric, nbt_type, default, conversions):
        self.name = name
        self.nbt_path_key = nbt_key
        self.nbt_type = nbt_type
        self.isnumeric = numeric
        self.default_val = default
        self.conversions = conversions
        self.__LOOKUP[name] = self

    def __str__(self):
        return 'VarType(%s)' % (self.name)

    def to_int(self, val):
        return self.conversions.to_int(val)

    @property
    def scale(self):
        return self.conversions.scale

    @classmethod
    def _init_from_parser(cls, value):
        return cls.__LOOKUP[value]

    # pickle the singleton
    def __reduce__(self):
        return 'VarType.%s' % self.name

    i32 = None
    nbt = None
    # https://en.wikipedia.org/wiki/Q_%28number_format%29
    q10 = None class LocalStackVariable(NbtOffsetVariable):

    def __init__(self, type, namespace, offset):
        super().__init__(type, namespace, offset)
        self.frame_depth = 0

    @property
    def path_type(self):
        return c.StackFrameHead if self.frame_depth == 0 \
               else c.StackFrame(self.frame_depth)

    def realign_frame(self, shift):
        self.frame_depth += shift class VirtualStackPointer(LocalStackVariable):
    path_type = c.StackPath # out-of-bounds stack path class CompilerVariable(Variable):

    def __init__(self, type):
        super().__init__(type)
        self.value = None

    def clone(self):
        v = CompilerVariable(self.type)
        v.value = self.value
        return v

    @property
    def namespace(self):
        assert False

    def _store_from_cmd(self, cmd, out):
        assert False, "Attempted store %s into %s" % (cmd, self)

    def read(self):
        assert False

    def set_const_val(self, val):
        assert False

    def get_value(self):
        return self.value

    def set_value(self, value):
        if self.type == VarType.i32:
            value = int(value)
        elif self.type == VarType.q10:
            value = float(value)
        self.value = value class NBTBase(HolderHolder, Resolvable, NativeType):

    def declare(self):
        pass class NBTList(RecurseMixin):

    type = NBTType.list

    def __init__(self, type):
        super().__init__()
        self.list_type = type
        self.items = []

    def append(self, item):
        assert isinstance(item, NBTBase)
        assert item.type == self.list_type or self.list_type is None
        self.items.append(item)
        self.hold(item)

    def declare(self):
        for item in self.items:
            item.declare()

    def clone(self):
        copy = NBTList(self.list_type)
        copy.items.extend(i.clone() for i in self.items)
        return copy

    def recurse(self, apply):
        maybetype = ''
        if self.list_type == NBTType.byte:
            maybetype = 'B;'
        elif self.list_type == NBTType.int:
            maybetype = 'I;'
        elif self.list_type == NBTType.long:
            maybetype = 'L;'
        return '[%s%s]' % (maybetype, ','.join(apply(item) for item \
                                               in self.items)) class NBTType(NativeType):

    __LOOKUP = {}

    def __init__(self, typename, compound=False):
        self.name = typename
        self._compound = compound
        self.__LOOKUP[typename] = self

    @property
    def exec_store_name(self):
        assert self.isnumeric
        # Currently we have the same names
        return self.name

    @property
    def isnumeric(self):
        return not self._compound and self.name != 'string'

    def __str__(self):
        return 'NBTType(%s)' % self.name

    def serialize(self):
        return self.name

    @classmethod
    def _init_from_parser(cls, value):
        return cls.__LOOKUP[value]

    def new(self, *args):
        # There are better ways of doing this
        if self is self.byte:
            impl = NBTByte
        elif self is self.short:
            impl = NBTShort
        elif self is self.int:
            impl = NBTInt
        elif self is self.long:
            impl = NBTLong
        elif self is self.float:
            impl = NBTFloat
        elif self is self.double:
            impl = NBTDouble
        elif self is self.string:
            impl = NBTString
        elif self is self.list:
            impl = NBTList
        elif self is self.compound:
            impl = NBTCompound
        else:
            assert False, str(self)
        return impl(*args)

    byte = None
    short = None
    int = None
    long = None
    float = None
    double = None
    string = None
    list = None
    compound = None class NBTCompound(RecurseMixin):

    type = NBTType.compound

    def __init__(self, items=[]):
        super().__init__()
        self.items = OrderedDict(items)
        for v in items:
            self.hold(v)

    def set(self, name, value):
        assert isinstance(name, str)
        assert isinstance(value, NBTBase)
        self.items[name] = value
        self.hold(value)

    def declare(self):
        for item in self.items.values():
            item.declare()

    def clone(self):
        return NBTCompound((k, v.clone()) for k, v in self.items.items())

    def recurse(self, apply):
        # TODO quote keys
        return '{%s}' % (','.join('%s:%s' % (k, apply(v)) for k, v\
                                             in self.items.items())) class FuncRefNBTString(NBTString):

    def __init__(self, func):
        HolderHolder.__init__(self)
        self._func = self.hold(func)

    def declare(self):
        self._func.val.usage()

    def clone(self):
        return FuncRefNBTString(self._func.val)

    def resolve(self, scope):
        fn = Function(self._func.val.global_name)
        return self.quote(fn.resolve(scope))

    def serialize(self):
        assert False class NBTByte(NBTValue):

    type = NBTType.byte
    validator = int

    def serialize(self):
        return '%db' % self.val
from ._core import (RuntimeInsn, RunAndCompileInsn, SingleCommandInsn,
                    READ, WRITE, TupleQueryResult, STACK_HEAD)
from ..core import BasicBlock, VisibleFunction, FunctionLike, CmdWriter
from ..core_types import (Opt,
                          )
from ..variables import (Variable, VarType, LocalStackVariable,
                         VirtualStackPointer, CompilerVariable)
from ..nbt import (NBTBase, NBTList, NBTType, NBTCompound, FuncRefNBTString,
                   NBTByte)
import commands as c
        import operator
"""Control Flow"""


class Branch(RunAndCompileInsn, SingleCommandInsn):
    """Unconditionally branch to the given label."""

    args = [BasicBlock]
    argnames = 'label'
    argdocs = ["Destination to branch to"]
    insn_name = 'branch'
    is_block_terminator = True
    is_branch = True

    def declare(self):
        self.label.usage()

    def activate(self, seq):
        assert self.label._func == seq._func
        if self.label == seq._func._exitblock:
            # Same restriction as Return
            assert not seq.is_function, seq

    def get_cmd(self, func):
        return c.Function(self.label.global_name)

    def run(self, ev):
        ev.jump(self.label)

    def serialize(self, holder):
        if self.label == self.label._func._exitblock:
            return 'ret'
        return super().serialize(holder)

class Call(Branch):
    """'calls' a label instead of branching. The label must be tagged with the
    'function' modifier. Control will resume to the next instruction after the
    label has been executed."""

    is_block_terminator = False
    argdocs = ["Label tagged as a function"]
    insn_name = 'call'

    def get_cmd(self, func):
        assert self.label.is_function, self.label
        return super().get_cmd(func)

    def run(self, ev):
        ev.fork_jump(self.label)


def make_stack_frame_from(values, out, destns):
    stack_move = out.namespace == destns or destns is None
    stack = NBTList(NBTType.compound)
    for val in values:
        item = NBTCompound()
        if type(val) == int:
            default = val
            vtype = VarType.i32
        elif type(val) == float:
            default = val
            vtype = VarType.q10
        elif isinstance(val, Variable):
            vtype = val.type
            default = vtype.default_val
        elif isinstance(val, VarType):
            vtype = val
            default = val.default_val
        elif isinstance(val, NBTBase):
            stack.append(val)
            continue
        else:
            assert False, val
        item.set(vtype.nbt_path_key, vtype.nbt_type.new(default))
        stack.append(item)
    frame = NBTCompound()
    frame.set('stack', stack)
    out.write(c.DataModifyStack(None, None, 'append', frame, destns))
    for i, val in enumerate(values):
        if isinstance(val, Variable):
            dest = LocalStackVariable(val.type, destns, i)
            if stack_move:
                # Variable has moved down to the previous stack frame
                val.realign_frame(1)
            val.clone_to(dest, out)
            if stack_move:
                val.realign_frame(-1)

class Invoke(RuntimeInsn):
    """Invokes a function."""


    args = [VisibleFunction, Opt(tuple), Opt(tuple)]