"""Data structure for LLVM AST.""" from collections import namedtuple from enum import Enum class SimpleType(Enum): """Simple types in LLVM.""" Void = 1 I1 = 2 I8 = 3 I32 = 4 I64 = 5 def __repr__(self): if self == SimpleType.Void: return 'void' elif self == SimpleType.I1: return 'i1' elif self == SimpleType.I8: return 'i8' elif self == SimpleType.I32: return 'i32' elif self == SimpleType.I64: return 'i64' else: return str(self) Program = namedtuple('Program', ['tdecls', 'gdecls', 'fdecls']) TypeDec = namedtuple('TypeDec', ['name', 'body']) PointerType = namedtuple('PointerType', ['inner_ty']) StructType = namedtuple('StructType', ['fields']) ArrayType = namedtuple('ArrayType', ['length', 'inner_ty']) FunctionType = namedtuple('FunctionType', ['return_ty', 'parameters']) NamedType = namedtuple('NamedType', ['other_name']) GlobalDec = namedtuple('GlobalDec', ['name', 'ty', 'body']) GNull = namedtuple('GNull', []) GGid = namedtuple('GGid', ['val']) GInt = namedtuple('GInt', ['val']) GString = namedtuple('GString', ['val']) GArray = namedtuple('GArray', ['entries']) GStruct = namedtuple('GStruct', ['fields']) FunctionDec = namedtuple('FunctionDec', ['return_type', 'name', 'parameters', 'body']) FunctionBody = namedtuple('FunctionBody', ['first_block', 'named_blocks']) Block = namedtuple('Block', ['insns', 'terminator']) Binop = namedtuple('Binop', ['bop', 'ty', 'left', 'right']) Alloca = namedtuple('Alloca', ['ty']) Load = namedtuple('Load', ['ty', 'oper']) Store = namedtuple('Store', ['ty', 'value', 'location']) Icmp = namedtuple('Icmp', ['cnd', 'ty', 'left', 'right']) Call = namedtuple('Call', ['return_ty', 'callee', 'arguments']) Bitcast = namedtuple('Bitcast', ['from_ty', 'oper', 'to_ty']) Gep = namedtuple('Gep', ['base_ty', 'oper_ty', 'oper', 'steps']) Zext = namedtuple('Zext', ['from_ty', 'oper', 'to_ty']) Ptrtoint = namedtuple('Ptrtoint', ['pointer_ty', 'oper', 'to_ty']) Ret = namedtuple('Ret', ['ty', 'oper']) Br = namedtuple('Br', ['label']) Cbr = namedtuple('Cbr', ['ty', 'oper', 'then_label', 'else_label']) Null = namedtuple('Null', []) Const = namedtuple('Const', ['val']) Gid = namedtuple('Gid', ['val']) Id = namedtuple('Id', ['val']) def ty2s(ty): if isinstance(ty, SimpleType): return repr(ty) elif isinstance(ty, PointerType): return ty2s(ty.inner_ty) + '*' else: # TODO print('Unknown type: {}' .format(ty)) return str(ty) def oper2s(operand): if isinstance(operand, Const): return str(operand.val) elif isinstance(operand, Id): return '%' + operand.val else: # TODO print('Unknown operand: {}' .format(operand)) def insn2s(insn): if isinstance(insn, Binop): return ('{} {} {}, {}' .format(insn.bop, ty2s(insn.ty), oper2s(insn.left), oper2s(insn.right))) elif isinstance(insn, Icmp): return ('icmp {} {} {}, {}' .format(insn.cnd, ty2s(insn.ty), oper2s(insn.left), oper2s(insn.right))) else: # TODO print('Unknown insn: {}' .format(insn))