class Type:
+ """Base class for all types."""
- __all = {}
- __seq = 0
+ __tags = set()
- def __init__(self, expr, id = ''):
+ def __init__(self, expr, tag = None):
self.expr = expr
-
- for char in id:
- assert char.isalnum() or char in '_ '
- id = id.replace(' ', '_')
-
- if id in Type.__all:
- Type.__seq += 1
- id += str(Type.__seq)
-
- assert id not in Type.__all
- Type.__all[id] = self
+ # Generate a default tag, used when naming functions that will operate
+ # on this type, so it should preferrably be something representative of
+ # the type.
+ if tag is None:
+ tag = ''.join([c for c in expr if c.isalnum() or c in '_'])
+ else:
+ for c in tag:
+ assert c.isalnum() or c in '_'
+
+ # Ensure it is unique.
+ if tag in Type.__tags:
+ suffix = 1
+ while tag + str(suffix) in Type.__tags:
+ suffix += 1
+ tag += str(suffix)
- self.id = id
+ assert tag not in Type.__tags
+ Type.__tags.add(tag)
+
+ self.tag = tag
def __str__(self):
+ """Return the C/C++ type expression for this type."""
return self.expr
def visit(self, visitor, *args, **kwargs):
class _Void(Type):
+ """Singleton void type."""
def __init__(self):
Type.__init__(self, "void")
class Literal(Type):
- def __init__(self, expr, format, base=10):
+ def __init__(self, expr, format):
Type.__init__(self, expr)
self.format = format
# The most legible
expr = "const " + type.expr
- Type.__init__(self, expr, 'C' + type.id)
+ Type.__init__(self, expr, 'C' + type.tag)
self.type = type
class Pointer(Type):
def __init__(self, type):
- Type.__init__(self, type.expr + " *", 'P' + type.id)
+ Type.__init__(self, type.expr + " *", 'P' + type.tag)
self.type = type
def visit(self, visitor, *args, **kwargs):
class Handle(Type):
def __init__(self, name, type, range=None, key=None):
- Type.__init__(self, type.expr, 'P' + type.id)
+ Type.__init__(self, type.expr, 'P' + type.tag)
self.name = name
self.type = type
self.range = range
class Enum(Type):
+ __id = 0
+
def __init__(self, name, values):
Type.__init__(self, name)
+
+ self.id = Enum.__id
+ Enum.__id += 1
+
self.values = list(values)
-
+
def visit(self, visitor, *args, **kwargs):
return visitor.visit_enum(self, *args, **kwargs)
class Bitmask(Type):
+ __id = 0
+
def __init__(self, type, values):
Type.__init__(self, type.expr)
+
+ self.id = Bitmask.__id
+ Bitmask.__id += 1
+
self.type = type
self.values = values
class Struct(Type):
+ __id = 0
+
def __init__(self, name, members):
Type.__init__(self, name)
+
+ self.id = Struct.__id
+ Struct.__id += 1
+
self.name = name
self.members = members
class Function:
- __id = 0
+ # 0-3 are reserved to memcpy, malloc, free, and realloc
+ __id = 4
def __init__(self, type, name, args, call = '', fail = None, sideeffects=True):
self.id = Function.__id
self.args[index].index = index + 1
-def WrapPointer(type):
- return Pointer(type)
-
-
class String(Type):
def __init__(self, expr = "char *", length = None):
return Opaque(type.expr + ' *')
+class Polymorphic(Type):
+
+ def __init__(self, default_type, switch_expr, switch_types):
+ Type.__init__(self, default_type.expr)
+ self.default_type = default_type
+ self.switch_expr = switch_expr
+ self.switch_types = switch_types
+
+ def visit(self, visitor, *args, **kwargs):
+ return visitor.visit_polymorphic(self, *args, **kwargs)
+
+ def iterswitch(self):
+ cases = [['default']]
+ types = [self.default_type]
+
+ for expr, type in self.switch_types:
+ case = 'case %s' % expr
+ try:
+ i = types.index(type)
+ except ValueError:
+ cases.append([case])
+ types.append(type)
+ else:
+ cases[i].append(case)
+
+ return zip(cases, types)
+
+
class Visitor:
def visit(self, type, *args, **kwargs):
def visit_interface(self, interface, *args, **kwargs):
raise NotImplementedError
+ def visit_polymorphic(self, polymorphic, *args, **kwargs):
+ raise NotImplementedError
+ #return self.visit(polymorphic.default_type, *args, **kwargs)
+
class OnceVisitor(Visitor):
def visit_opaque(self, opaque):
return opaque
+ def visit_polymorphic(self, polymorphic):
+ default_type = self.visit(polymorphic.default_type)
+ switch_expr = polymorphic.switch_expr
+ switch_types = [(expr, self.visit(type)) for expr, type in polymorphic.switch_types]
+ return Polymorphic(default_type, switch_expr, switch_types)
+
class Collector(Visitor):
'''Collect.'''
self.visit(arg.type)
self.visit(method.type)
+ def visit_polymorphic(self, polymorphic):
+ self.visit(polymorphic.default_type)
+ for expr, type in polymorphic.switch_types:
+ self.visit(type)
+
class API: