# Path: awake/operand.py
# class ComplexValue(Operand):
#     def __init__(self, hint='complex', deps=None):
#         self.hint = hint
#         if deps:
#             self.deps = deps
#         else:
#             self.deps = set()
# 
#     def isComplex(self):
#         return True
# 
#     def getDependencies(self):
#         return self.deps
# 
#     def __str__(self):
#         return '#'+self.hint+':'+(','.join(str(dep) for dep in self.deps if not isinstance(dep, address.Address)))+'#'
# 
# Path: awake/operator.py
# class HighByte(FuncOperator):
#     name = 'hi'
# 
#     @staticmethod
#     def calculate(arg):
#         return arg >> 8
# 
# class LowByte(FuncOperator):
#     name = 'lo'
# 
#     @staticmethod
#     def calculate(arg):
#         return arg & 0xFF
# 
# class Word(FuncOperator):
#     name = 'word'
#     bits = 16
# 
#     @staticmethod
#     def calculate(hi, lo):
#         return (hi << 8) | lo
# 
#     @classmethod
#     def make(cls, hi, lo):
#         # merge word
#         if isinstance(hi, HighByte) and isinstance(lo, LowByte):
#             if hi.childs[0] == lo.childs[0]:
#                 return hi.childs[0]
# 
#         # high zero
#         if hi.value == 0:
#             return lo
# 
#         if isinstance(hi, Shr) and isinstance(lo, Shl) and hi.left == lo.left and isConstant(hi.right) and isConstant(lo.right):
#             hi_sh = hi.right.value
#             lo_sh = lo.right.value
#             if hi_sh + lo_sh == 8:
#                 return Shl16.make(lo.left, Constant(lo_sh))
# 
#         return super(Word, cls).make(hi, lo)
# 
# class LogicalNot(Operator):
#     bits = 1
# 
#     def __str__(self):
#         return 'not '+str(self.childs[0])
# 
#     @classmethod
#     def make(cls, inner):
#         try:
#             return inner.logicalNot()
#         except AttributeError:
#             return super(LogicalNot, cls).make(inner)


from awake.operand import ComplexValue
from awake.operator import HighByte, LowByte, Word, LogicalNot
    def invalidate(self, register):
        delete = set()

        for x in self.values:
            if self.values[x] and register in self.values[x].getDependencies():
                delete.add(x)

        for x in delete:
            del(self.values[x])

    def hasValue(self, register):
        if register in ('BC', 'DE', 'HL'):
            return self.hasValue(register[0]) and self.hasValue(register[1])
        if register == 'FNZ':
            return self.hasValue('FZ')
        if register == 'FNC':
            return self.hasValue('FC')
        if register not in self.values:
            return False
        value = self.values[register]
        try:
            return not value.isComplex()
        except AttributeError:
            return True

    def hasConstantValue(self, register):
        return self.hasValue(register) and self.getValue(register).value is not None

    def getValue(self, register):
        if register in ('BC', 'DE', 'HL'):

# Path: awake/operand.py
# class ComplexValue(Operand):
#     def __init__(self, hint='complex', deps=None):
#         self.hint = hint
#         if deps:
#             self.deps = deps
#         else:
#             self.deps = set()
# 
#     def isComplex(self):
#         return True
# 
#     def getDependencies(self):
#         return self.deps
# 
#     def __str__(self):
#         return '#'+self.hint+':'+(','.join(str(dep) for dep in self.deps if not isinstance(dep, address.Address)))+'#'
# 
# Path: awake/operator.py
# class HighByte(FuncOperator):
#     name = 'hi'
# 
#     @staticmethod
#     def calculate(arg):
#         return arg >> 8
# 
# class LowByte(FuncOperator):
#     name = 'lo'
# 
#     @staticmethod
#     def calculate(arg):
#         return arg & 0xFF
# 
# class Word(FuncOperator):
#     name = 'word'
#     bits = 16
# 
#     @staticmethod
#     def calculate(hi, lo):
#         return (hi << 8) | lo
# 
#     @classmethod
#     def make(cls, hi, lo):
#         # merge word
#         if isinstance(hi, HighByte) and isinstance(lo, LowByte):
#             if hi.childs[0] == lo.childs[0]:
#                 return hi.childs[0]
# 
#         # high zero
#         if hi.value == 0:
#             return lo
# 
#         if isinstance(hi, Shr) and isinstance(lo, Shl) and hi.left == lo.left and isConstant(hi.right) and isConstant(lo.right):
#             hi_sh = hi.right.value
#             lo_sh = lo.right.value
#             if hi_sh + lo_sh == 8:
#                 return Shl16.make(lo.left, Constant(lo_sh))
# 
#         return super(Word, cls).make(hi, lo)
# 
# class LogicalNot(Operator):
#     bits = 1
# 
#     def __str__(self):
#         return 'not '+str(self.childs[0])
# 
#     @classmethod
#     def make(cls, inner):
#         try:
#             return inner.logicalNot()
#         except AttributeError:
#             return super(LogicalNot, cls).make(inner)


# Path: awake/context.py
from awake.operand import ComplexValue
from awake.operator import HighByte, LowByte, Word, LogicalNot

    def invalidate(self, register):
        delete = set()

        for x in self.values:
            if self.values[x] and register in self.values[x].getDependencies():
                delete.add(x)

        for x in delete:
            del(self.values[x])

    def hasValue(self, register):
        if register in ('BC', 'DE', 'HL'):
            return self.hasValue(register[0]) and self.hasValue(register[1])
        if register == 'FNZ':
            return self.hasValue('FZ')
        if register == 'FNC':
            return self.hasValue('FC')
        if register not in self.values:
            return False
        value = self.values[register]
        try:
            return not value.isComplex()
        except AttributeError:
            return True

    def hasConstantValue(self, register):
        return self.hasValue(register) and self.getValue(register).value is not None

    def getValue(self, register):
        if register in ('BC', 'DE', 'HL'):

            return Word(self.getValue(register[0]), self.getValue(register[1])).optimizedWithContext(Context())