Skip to content

Instantly share code, notes, and snippets.

@mrh1997
Last active August 29, 2015 14:22
Show Gist options
  • Save mrh1997/876070be3763733f849e to your computer and use it in GitHub Desktop.
Save mrh1997/876070be3763733f849e to your computer and use it in GitHub Desktop.
This Gist is a proposal for an alternative to the current 'Type' object of the MatthieuDartiailh/pyclibrary
class CLibType(object):
def __init__(self, quals=None):
self.quals = quals or []
@property
def ptr(self):
return PointerType(self)
def eval(self, typemap):
"""
:returns: The evaluated type
"""
raise NotImplementedError()
class BaseType(CLibType):
def __init__(self, name, quals=None):
super(Integer, self).__init__(quals)
self.name = name
class StructType(CLibType):
def __init__(self, field_types, field_names, packsize, quals=None):
assert len(field_types) == len(field_names)
super(StructType, self).__init__(quals)
self.fields = field_types
self.field_names = field_names
self.packsize = packsize
class BitFieldType(CLibType):
def __init__(self, base_type, field_sizes, field_names, quals=None):
assert isinstance(base_type, IntType)
assert len(field_sizes) == len(field_names)
super(BitFieldType, self).__init__(quals)
self.base = base_type
self.field_sizes = field_sizes
self.field_names = field_names
class UnionType(CLibType):
def __init__(self, field_types, field_names, quals=None):
assert len(field_types) == len(field_names)
super(UnionType, self).__init__(quals)
self.fields = field_types
self.field_names = field_names
class EnumType(IntType):
def __init__(self, names, values, quals=None):
assert len(names) == len(values)
super(EnumType, self).__init__(quals)
self.names = names
self.values = values
class PointerType(CLibType):
def __init__(self, ref_type, quals=None):
super(PointerType, self).__init__(quals)
self.ref = ref_type
class ArrayType(CLibType):
def __init__(self, base_type, count, quals=None):
super(ArrayType, self).__init__(quals)
self.base = base_type
self.count = count
class FunctionType(CLibType):
def __init__(self, result_type, param_types=None, param_names=None,
quals=None):
super(Function, self).__init__(quals=quals)
self.result = result_type
self.params = param_types or []
self.param_names = param_names or []
assert len(self.param_names) == len(self.param_Types)
class RefType(CLibType):
def __init__(self, type_name, quals):
super(RefType, self).__init__(quals)
self.type_name = type_name
class MacroDef(object):
def __init__(self, value, params_names=None):
"""
:param str value: the text, that shall be inserted instead of the macro call
:param list[str]|None param_names: the list of parameter names or None,
if this is a constant macro definition without parameters
"""
self.param_names = param_names
self.value = value
class CLibInterface(object):
def __init__(self):
self.types = dict()
self.globals = dict()
self.macros = dict()
class CParser(object):
def __init__(self, prop_type_quals=None):
"""
creates a parser object, that is customized for a specific
compiler (i.e. the microsoft compiler will support different
type_quals than GCC
"""
# ...
def parse(self, *hdr_files):
clibIntf = CLibInterface()
for hdr_file in hdr_files:
if isinstance(hdr_file, basestring):
hdr_file = file(hdr_file, "rt")
# parse types, macrodefs and global objects of hdr_file into clibIntf
return clibIntf
if __name__ == "__main__":
parser = CParser(['__far', '__cdecl(export)', '__near', '__stdcall'])
test = parser.parse(StringIO("__stdcall unsigned int * a(int, struct _s p2);"))
assert test.globals('a') == \
FunctionType(
result_type=PointerType(BaseType('unsigned int')),
param_types=[
BaseType('int'),
RefType('struct _s')],
param_names=[
None,
'p2'],
quals=['__stdcall'])
test2 = parser.parse(StringIO("void (*a[3])();"))
assert test2.types('a') == \
ArrayType(
base_type=PointerType(
FunctionType(
BaseType(void)) ),
count=3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment