131 lines
4.1 KiB
Python
131 lines
4.1 KiB
Python
"""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('ty2s: 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('oper2s: 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('insn2s: Unknown insn: {}'
|
|
.format(insn))
|
|
|
|
def terminator2s(terminator):
|
|
if isinstance(terminator, Ret):
|
|
if terminator.oper is None:
|
|
return ('ret {}'
|
|
.format(ty2s(terminator.ty)))
|
|
else:
|
|
return ('ret {} {}'
|
|
.format(ty2s(terminator.ty),
|
|
oper2s(terminator.oper)))
|
|
elif isinstance(terminator, Br):
|
|
return ('br label %{}'
|
|
.format(terminator.label))
|
|
elif isinstance(terminator, Cbr):
|
|
return ('br {} {}, label %{}, label %{}'
|
|
.format(ty2s(terminator.ty),
|
|
oper2s(terminator.oper),
|
|
terminator.then_label,
|
|
terminator.else_label))
|
|
else:
|
|
print('terminator2s: Unknown terminator {}'
|
|
.format(terminator))
|