# Path: c_comp/ir.py
# class IR:
# 
#     _counter = 0
# 
#     FunctionBegin = namedtuple('FunctionBegin', 'name storage pragma')
#     FunctionEnd = namedtuple('FunctionEnd', '')
# 
#     Label = namedtuple('Label', 'label')
#     EntityLocalVar = namedtuple('EntityLocalVar', 'name offset specific')
# 
#     Jump = namedtuple('Jump', 'dest')
#     JumpIf = namedtuple('JumpIf', 'dest cond')
#     JumpIfNot = namedtuple('JumpIfNot', 'dest cond')
# 
#     Push = namedtuple('Push', 'src')
#     Pop = namedtuple('Pop', 'dest')
#     Call = namedtuple('Call', 'name')
#     Return = namedtuple('Return', '')
#     Print = namedtuple('Print', 'args')
# 
#     Move = namedtuple('Move', 'src dest')
# 
#     Sync = namedtuple('Sync', '')
#     Test = namedtuple('Test', 'cmd dest')
#     Asm = namedtuple('Asm', 'args')
#     ExecSel = namedtuple('ExecSel', 'label exec_type sel_type args')
#     ExecEnd = namedtuple('ExecSelEnd', 'label')
#     ExecChain = namedtuple('ExecChain', 'label exec_type args')
# 
#     StackPointer = namedtuple('StackPointer', 'type')(IntType())
#     BasePointer = namedtuple('BasePointer', 'type')(IntType())
#     GlobalIndex = namedtuple('GlobalIndex', 'type')(IntType())
#     EntityLocalBase = namedtuple('EntityLocalBase', 'type')(IntType())
#     ReturnRegister = namedtuple('ReturnRegister', 'type')(IntType())
# 
#     SlotOffset = namedtuple('SlotOffset', 'base offset type')
#     GlobalSlot = namedtuple('GlobalSlot', 'offset type')
#     EntityLocalSlot = namedtuple('EntityLocalSlot', 'offset type')
#     Dereference = namedtuple('Dereference', 'addr type')
#     Free = namedtuple('Free', 'slot')
# 
#     class Slot(namedtuple('Slot', 'idx type')):
#         def __new__(cls, type):
#             IR._counter += 1
#             return tuple.__new__(cls, (IR._counter, type))
# 
#     Operation = namedtuple('Operation', 'op left right dest')
#     UnaryOperation = namedtuple('UnaryOperation', 'op val dest')
# 
#     LiteralString = namedtuple('LiteralString', 'val type')
#     LiteralInt = namedtuple('LiteralInt', 'val type')
# 
#     class Op:
# 
#         Add = namedtuple('Add', '')()
#         Sub = namedtuple('Sub', '')()
#         Mul = namedtuple('Mul', '')()
#         Div = namedtuple('Div', '')()
#         Mod = namedtuple('Mod', '')()
#         Shl = namedtuple('Shl', '')()
#         Shr = namedtuple('Shr', '')()
#         And = namedtuple('And', '')()
#         Xor = namedtuple('Xor', '')()
#         Or = namedtuple('Or', '')()
#         Eq = namedtuple('Eq', '')()
#         Neq = namedtuple('Neq', '')()
#         Lt = namedtuple('Lt', '')()
#         Gt = namedtuple('Gt', '')()
#         LtEq = namedtuple('LtEq', '')()
#         GtEq = namedtuple('GtEq', '')()
#         LogOr = namedtuple('LogOr', '')()
#         LogAnd = namedtuple('LogAnd', '')()
# 
#         @classmethod
#         def lookup(cls, op):
#             return {
#                 '+': cls.Add,
#                 '-': cls.Sub,
#                 '*': cls.Mul,
#                 '/': cls.Div,
#                 '%': cls.Mod,
#                 '<<': cls.Shl,
#                 '>>': cls.Shr,
#                 '&': cls.And,
#                 '^': cls.Xor,
#                 '|': cls.Or,
#                 '==': cls.Eq,
#                 '!=': cls.Neq,
#                 '<': cls.Lt,
#                 '>': cls.Gt,
#                 '<=': cls.LtEq,
#                 '>=': cls.GtEq,
#                 '||': cls.LogOr,
#                 '&&': cls.LogAnd
#             }[op]
# 
#     class UnaryOp:
# 
#         AddrOf = namedtuple('AddrOf', '')()
#         Deref = namedtuple('Deref', '')()
#         IntPromote = namedtuple('IntPromote', '')()
#         Negate = namedtuple('Negate', '')()
#         Not = namedtuple('Not', '')()
#         LogNot = namedtuple('LogNot', '')()
# 
# 
#         @classmethod
#         def lookup(cls, op):
#             return {
#                 '&': cls.AddrOf,
#                 '*': cls.Deref,
#                 '+': cls.IntPromote,
#                 '-': cls.Negate,
#                 '~': cls.Not,
#                 '!': cls.LogNot
#             }[op]
# 
# Path: c_comp/nodes.py
# class IdentifierExpr(Expression):  props = ('val',)


from ..ir import IR
from ..nodes import IdentifierExpr

def add_tag(visitor, expr):
    assert len(expr.args) == 1, "add_tag_this_entity takes 1 argument"
    arg = visitor.visit_expression(expr.args[0])

# Path: c_comp/ir.py
# class IR:
# 
#     _counter = 0
# 
#     FunctionBegin = namedtuple('FunctionBegin', 'name storage pragma')
#     FunctionEnd = namedtuple('FunctionEnd', '')
# 
#     Label = namedtuple('Label', 'label')
#     EntityLocalVar = namedtuple('EntityLocalVar', 'name offset specific')
# 
#     Jump = namedtuple('Jump', 'dest')
#     JumpIf = namedtuple('JumpIf', 'dest cond')
#     JumpIfNot = namedtuple('JumpIfNot', 'dest cond')
# 
#     Push = namedtuple('Push', 'src')
#     Pop = namedtuple('Pop', 'dest')
#     Call = namedtuple('Call', 'name')
#     Return = namedtuple('Return', '')
#     Print = namedtuple('Print', 'args')
# 
#     Move = namedtuple('Move', 'src dest')
# 
#     Sync = namedtuple('Sync', '')
#     Test = namedtuple('Test', 'cmd dest')
#     Asm = namedtuple('Asm', 'args')
#     ExecSel = namedtuple('ExecSel', 'label exec_type sel_type args')
#     ExecEnd = namedtuple('ExecSelEnd', 'label')
#     ExecChain = namedtuple('ExecChain', 'label exec_type args')
# 
#     StackPointer = namedtuple('StackPointer', 'type')(IntType())
#     BasePointer = namedtuple('BasePointer', 'type')(IntType())
#     GlobalIndex = namedtuple('GlobalIndex', 'type')(IntType())
#     EntityLocalBase = namedtuple('EntityLocalBase', 'type')(IntType())
#     ReturnRegister = namedtuple('ReturnRegister', 'type')(IntType())
# 
#     SlotOffset = namedtuple('SlotOffset', 'base offset type')
#     GlobalSlot = namedtuple('GlobalSlot', 'offset type')
#     EntityLocalSlot = namedtuple('EntityLocalSlot', 'offset type')
#     Dereference = namedtuple('Dereference', 'addr type')
#     Free = namedtuple('Free', 'slot')
# 
#     class Slot(namedtuple('Slot', 'idx type')):
#         def __new__(cls, type):
#             IR._counter += 1
#             return tuple.__new__(cls, (IR._counter, type))
# 
#     Operation = namedtuple('Operation', 'op left right dest')
#     UnaryOperation = namedtuple('UnaryOperation', 'op val dest')
# 
#     LiteralString = namedtuple('LiteralString', 'val type')
#     LiteralInt = namedtuple('LiteralInt', 'val type')
# 
#     class Op:
# 
#         Add = namedtuple('Add', '')()
#         Sub = namedtuple('Sub', '')()
#         Mul = namedtuple('Mul', '')()
#         Div = namedtuple('Div', '')()
#         Mod = namedtuple('Mod', '')()
#         Shl = namedtuple('Shl', '')()
#         Shr = namedtuple('Shr', '')()
#         And = namedtuple('And', '')()
#         Xor = namedtuple('Xor', '')()
#         Or = namedtuple('Or', '')()
#         Eq = namedtuple('Eq', '')()
#         Neq = namedtuple('Neq', '')()
#         Lt = namedtuple('Lt', '')()
#         Gt = namedtuple('Gt', '')()
#         LtEq = namedtuple('LtEq', '')()
#         GtEq = namedtuple('GtEq', '')()
#         LogOr = namedtuple('LogOr', '')()
#         LogAnd = namedtuple('LogAnd', '')()
# 
#         @classmethod
#         def lookup(cls, op):
#             return {
#                 '+': cls.Add,
#                 '-': cls.Sub,
#                 '*': cls.Mul,
#                 '/': cls.Div,
#                 '%': cls.Mod,
#                 '<<': cls.Shl,
#                 '>>': cls.Shr,
#                 '&': cls.And,
#                 '^': cls.Xor,
#                 '|': cls.Or,
#                 '==': cls.Eq,
#                 '!=': cls.Neq,
#                 '<': cls.Lt,
#                 '>': cls.Gt,
#                 '<=': cls.LtEq,
#                 '>=': cls.GtEq,
#                 '||': cls.LogOr,
#                 '&&': cls.LogAnd
#             }[op]
# 
#     class UnaryOp:
# 
#         AddrOf = namedtuple('AddrOf', '')()
#         Deref = namedtuple('Deref', '')()
#         IntPromote = namedtuple('IntPromote', '')()
#         Negate = namedtuple('Negate', '')()
#         Not = namedtuple('Not', '')()
#         LogNot = namedtuple('LogNot', '')()
# 
# 
#         @classmethod
#         def lookup(cls, op):
#             return {
#                 '&': cls.AddrOf,
#                 '*': cls.Deref,
#                 '+': cls.IntPromote,
#                 '-': cls.Negate,
#                 '~': cls.Not,
#                 '!': cls.LogNot
#             }[op]
# 
# Path: c_comp/nodes.py
# class IdentifierExpr(Expression):  props = ('val',)


# Path: c_comp/lib/entity.py
from ..ir import IR
from ..nodes import IdentifierExpr


def add_tag(visitor, expr):
    assert len(expr.args) == 1, "add_tag_this_entity takes 1 argument"
    arg = visitor.visit_expression(expr.args[0])

    assert isinstance(arg, IR.LiteralString), "Must be constant string"