1a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar"""Flexible enumeration of C types.""" 2a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 3a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarfrom Enumeration import * 4a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 5a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar# TODO: 6a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar# - struct improvements (flexible arrays, packed & 8a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar# unpacked, alignment) 9880c40345f903b087b52eb559cbd435f2ccac484Daniel Dunbar# - objective-c qualified id 10880c40345f903b087b52eb559cbd435f2ccac484Daniel Dunbar# - anonymous / transparent unions 11880c40345f903b087b52eb559cbd435f2ccac484Daniel Dunbar# - VLAs 12880c40345f903b087b52eb559cbd435f2ccac484Daniel Dunbar# - block types 13dda09c8704f47a17ca34e0aa7f3a0d3f8bc6f399Daniel Dunbar# - K&R functions 14dda09c8704f47a17ca34e0aa7f3a0d3f8bc6f399Daniel Dunbar# - pass arguments of different types (test extension, transparent union) 15dda09c8704f47a17ca34e0aa7f3a0d3f8bc6f399Daniel Dunbar# - varargs 16a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 17a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar### 18a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar# Actual type types 19a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 2098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbarclass Type: 2198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar def isBitField(self): 2298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar return False 2398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar 2498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar def isPaddingBitField(self): 2598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar return False 2698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar 276ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar def getTypeName(self, printer): 286ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar name = 'T%d' % len(printer.types) 296ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar typedef = self.getTypedefDef(name, printer) 306ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar printer.addDeclaration(typedef) 316ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar return name 326ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar 3398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbarclass BuiltinType(Type): 3498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar def __init__(self, name, size, bitFieldSize=None): 35a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.name = name 36789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar self.size = size 3798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar self.bitFieldSize = bitFieldSize 3898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar 3998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar def isBitField(self): 4098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar return self.bitFieldSize is not None 4198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar 4298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar def isPaddingBitField(self): 4398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar return self.bitFieldSize is 0 4498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar 4598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar def getBitFieldSize(self): 4698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar assert self.isBitField() 4798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar return self.bitFieldSize 48789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar 496ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar def getTypeName(self, printer): 506ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar return self.name 516ffef197e9388a54f983bfd86931119e0885ce51Daniel Dunbar 52789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar def sizeof(self): 53789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar return self.size 54a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 55a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __str__(self): 56a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return self.name 57a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 5843ec96da71b94f064ed6a3031025208d23acd592Douglas Gregorclass EnumType(Type): 59176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines unique_id = 0 60176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 6143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor def __init__(self, index, enumerators): 6243ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor self.index = index 6343ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor self.enumerators = enumerators 64176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines self.unique_id = self.__class__.unique_id 65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines self.__class__.unique_id += 1 6643ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 6743ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor def getEnumerators(self): 6843ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor result = '' 6943ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor for i, init in enumerate(self.enumerators): 7043ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor if i > 0: 7143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor result = result + ', ' 72176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines result = result + 'enum%dval%d_%d' % (self.index, i, self.unique_id) 7343ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor if init: 7443ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor result = result + ' = %s' % (init) 7543ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 7643ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor return result 7743ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 7843ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor def __str__(self): 7943ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor return 'enum { %s }' % (self.getEnumerators()) 8043ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 8143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor def getTypedefDef(self, name, printer): 8243ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor return 'typedef enum %s { %s } %s;'%(name, self.getEnumerators(), name) 8343ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 8498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbarclass RecordType(Type): 85a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self, index, isUnion, fields): 86a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.index = index 87a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.isUnion = isUnion 88a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.fields = fields 89a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.name = None 90a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 9198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar def __str__(self): 9298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar def getField(t): 9398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar if t.isBitField(): 9498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar return "%s : %d;" % (t, t.getBitFieldSize()) 9598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar else: 9698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar return "%s;" % t 9798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar 98a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return '%s { %s }'%(('struct','union')[self.isUnion], 9998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar ' '.join(map(getField, self.fields))) 100a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 101a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def getTypedefDef(self, name, printer): 10298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar def getField((i, t)): 10398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar if t.isBitField(): 10498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar if t.isPaddingBitField(): 10598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar return '%s : 0;'%(printer.getTypeName(t),) 10698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar else: 10798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar return '%s field%d : %d;'%(printer.getTypeName(t),i, 10898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar t.getBitFieldSize()) 10998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar else: 11098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar return '%s field%d;'%(printer.getTypeName(t),i) 11198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar fields = map(getField, enumerate(self.fields)) 112a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar # Name the struct for more readable LLVM IR. 113a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return 'typedef %s %s { %s } %s;'%(('struct','union')[self.isUnion], 114a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar name, ' '.join(fields), name) 115a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 11698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbarclass ArrayType(Type): 117a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self, index, isVector, elementType, size): 118a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if isVector: 119a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar # Note that for vectors, this is the size in bytes. 120a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar assert size > 0 121a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 122a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar assert size is None or size >= 0 123a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.index = index 124a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.isVector = isVector 125a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.elementType = elementType 126a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.size = size 127789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar if isVector: 128789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar eltSize = self.elementType.sizeof() 129789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar assert not (self.size % eltSize) 130789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar self.numElements = self.size // eltSize 131789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar else: 132789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar self.numElements = self.size 133a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 134a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __str__(self): 135a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if self.isVector: 136a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return 'vector (%s)[%d]'%(self.elementType,self.size) 137a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar elif self.size is not None: 138a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return '(%s)[%d]'%(self.elementType,self.size) 139a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 140a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return '(%s)[]'%(self.elementType,) 141a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 142a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def getTypedefDef(self, name, printer): 143a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar elementName = printer.getTypeName(self.elementType) 144a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if self.isVector: 145a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return 'typedef %s %s __attribute__ ((vector_size (%d)));'%(elementName, 146a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar name, 147a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.size) 148a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 149a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if self.size is None: 150a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar sizeStr = '' 151a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 152a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar sizeStr = str(self.size) 153a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return 'typedef %s %s[%s];'%(elementName, name, sizeStr) 154a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 15598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbarclass ComplexType(Type): 156a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self, index, elementType): 157a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.index = index 158a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.elementType = elementType 159a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 160a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __str__(self): 161a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return '_Complex (%s)'%(self.elementType) 162a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 163a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def getTypedefDef(self, name, printer): 164a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return 'typedef _Complex %s %s;'%(printer.getTypeName(self.elementType), name) 165a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 16698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbarclass FunctionType(Type): 167a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self, index, returnType, argTypes): 168a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.index = index 169a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.returnType = returnType 170a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.argTypes = argTypes 171a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 172a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __str__(self): 173a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if self.returnType is None: 174a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar rt = 'void' 175a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 176a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar rt = str(self.returnType) 177a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if not self.argTypes: 178a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar at = 'void' 179a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 180a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar at = ', '.join(map(str, self.argTypes)) 181a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return '%s (*)(%s)'%(rt, at) 182a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 183a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def getTypedefDef(self, name, printer): 184a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if self.returnType is None: 185a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar rt = 'void' 186a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 187a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar rt = str(self.returnType) 188a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if not self.argTypes: 189a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar at = 'void' 190a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 191a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar at = ', '.join(map(str, self.argTypes)) 192a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return 'typedef %s (*%s)(%s);'%(rt, name, at) 193a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 194a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar### 195a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar# Type enumerators 196a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 197a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass TypeGenerator(object): 198a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self): 199a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.cache = {} 200a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 201a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def setCardinality(self): 202a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar abstract 203a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 204a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def get(self, N): 205a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar T = self.cache.get(N) 206a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if T is None: 207a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar assert 0 <= N < self.cardinality 208a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar T = self.cache[N] = self.generateType(N) 209a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return T 210a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 211a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def generateType(self, N): 212a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar abstract 213a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 214a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass FixedTypeGenerator(TypeGenerator): 215a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self, types): 216a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar TypeGenerator.__init__(self) 217a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.types = types 218a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.setCardinality() 219a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 220a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def setCardinality(self): 221a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.cardinality = len(self.types) 222a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 223a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def generateType(self, N): 224a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return self.types[N] 225a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 22643ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor# Factorial 22743ec96da71b94f064ed6a3031025208d23acd592Douglas Gregordef fact(n): 22843ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor result = 1 22943ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor while n > 0: 23043ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor result = result * n 23143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor n = n - 1 23243ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor return result 23343ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 23443ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor# Compute the number of combinations (n choose k) 23543ec96da71b94f064ed6a3031025208d23acd592Douglas Gregordef num_combinations(n, k): 23643ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor return fact(n) / (fact(k) * fact(n - k)) 23743ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 23843ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor# Enumerate the combinations choosing k elements from the list of values 23943ec96da71b94f064ed6a3031025208d23acd592Douglas Gregordef combinations(values, k): 24043ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor # From ActiveState Recipe 190465: Generator for permutations, 24143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor # combinations, selections of a sequence 24243ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor if k==0: yield [] 24343ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor else: 24443ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor for i in xrange(len(values)-k+1): 24543ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor for cc in combinations(values[i+1:],k-1): 24643ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor yield [values[i]]+cc 24743ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 24843ec96da71b94f064ed6a3031025208d23acd592Douglas Gregorclass EnumTypeGenerator(TypeGenerator): 24943ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor def __init__(self, values, minEnumerators, maxEnumerators): 25043ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor TypeGenerator.__init__(self) 25143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor self.values = values 25243ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor self.minEnumerators = minEnumerators 25343ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor self.maxEnumerators = maxEnumerators 25443ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor self.setCardinality() 25543ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 25643ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor def setCardinality(self): 25743ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor self.cardinality = 0 25843ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor for num in range(self.minEnumerators, self.maxEnumerators + 1): 25943ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor self.cardinality += num_combinations(len(self.values), num) 26043ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 26143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor def generateType(self, n): 26243ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor # Figure out the number of enumerators in this type 26343ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor numEnumerators = self.minEnumerators 26443ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor valuesCovered = 0 26543ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor while numEnumerators < self.maxEnumerators: 26643ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor comb = num_combinations(len(self.values), numEnumerators) 26743ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor if valuesCovered + comb > n: 26843ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor break 26943ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor numEnumerators = numEnumerators + 1 27043ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor valuesCovered += comb 27143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 27243ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor # Find the requested combination of enumerators and build a 27343ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor # type from it. 27443ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor i = 0 27543ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor for enumerators in combinations(self.values, numEnumerators): 27643ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor if i == n - valuesCovered: 27743ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor return EnumType(n, enumerators) 27843ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 27943ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor i = i + 1 28043ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 28143ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor assert False 28243ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 283a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass ComplexTypeGenerator(TypeGenerator): 284a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self, typeGen): 285a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar TypeGenerator.__init__(self) 286a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.typeGen = typeGen 287a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.setCardinality() 288a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 289a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def setCardinality(self): 290a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.cardinality = self.typeGen.cardinality 291a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 292a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def generateType(self, N): 293a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return ComplexType(N, self.typeGen.get(N)) 294a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 295a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass VectorTypeGenerator(TypeGenerator): 296a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self, typeGen, sizes): 297a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar TypeGenerator.__init__(self) 298a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.typeGen = typeGen 299a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.sizes = tuple(map(int,sizes)) 300a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.setCardinality() 301a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 302a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def setCardinality(self): 303a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.cardinality = len(self.sizes)*self.typeGen.cardinality 304a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 305a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def generateType(self, N): 306a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality) 307a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return ArrayType(N, True, self.typeGen.get(T), self.sizes[S]) 308a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 309a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass FixedArrayTypeGenerator(TypeGenerator): 310a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self, typeGen, sizes): 311a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar TypeGenerator.__init__(self) 312a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.typeGen = typeGen 313a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.sizes = tuple(size) 314a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.setCardinality() 315a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 316a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def setCardinality(self): 317a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.cardinality = len(self.sizes)*self.typeGen.cardinality 318a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 319a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def generateType(self, N): 320a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality) 321a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return ArrayType(N, false, self.typeGen.get(T), self.sizes[S]) 322a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 323a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass ArrayTypeGenerator(TypeGenerator): 324a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self, typeGen, maxSize, useIncomplete=False, useZero=False): 325a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar TypeGenerator.__init__(self) 326a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.typeGen = typeGen 327a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.useIncomplete = useIncomplete 328a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.useZero = useZero 329a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.maxSize = int(maxSize) 330a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.W = useIncomplete + useZero + self.maxSize 331a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.setCardinality() 332a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 333a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def setCardinality(self): 334a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.cardinality = self.W * self.typeGen.cardinality 335a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 336a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def generateType(self, N): 337a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S,T = getNthPairBounded(N, self.W, self.typeGen.cardinality) 338a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if self.useIncomplete: 339a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if S==0: 340a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar size = None 341a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S = None 342a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 343a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S = S - 1 344a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if S is not None: 345a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if self.useZero: 346a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar size = S 347a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 348a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar size = S + 1 349a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return ArrayType(N, False, self.typeGen.get(T), size) 350a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 351a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass RecordTypeGenerator(TypeGenerator): 352a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self, typeGen, useUnion, maxSize): 353a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar TypeGenerator.__init__(self) 354a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.typeGen = typeGen 355a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.useUnion = bool(useUnion) 356a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.maxSize = int(maxSize) 357a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.setCardinality() 358a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 359a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def setCardinality(self): 360a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar M = 1 + self.useUnion 361a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if self.maxSize is aleph0: 362a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S = aleph0 * self.typeGen.cardinality 363a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 364a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S = 0 365a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar for i in range(self.maxSize+1): 366a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S += M * (self.typeGen.cardinality ** i) 367a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.cardinality = S 368a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 369a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def generateType(self, N): 370a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar isUnion,I = False,N 371a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if self.useUnion: 372a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar isUnion,I = (I&1),I>>1 373a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar fields = map(self.typeGen.get,getNthTuple(I,self.maxSize,self.typeGen.cardinality)) 374a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return RecordType(N, isUnion, fields) 375a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 376a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass FunctionTypeGenerator(TypeGenerator): 377a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self, typeGen, useReturn, maxSize): 378a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar TypeGenerator.__init__(self) 379a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.typeGen = typeGen 380a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.useReturn = useReturn 381a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.maxSize = maxSize 382a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.setCardinality() 383a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 384a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def setCardinality(self): 385a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if self.maxSize is aleph0: 386a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S = aleph0 * self.typeGen.cardinality() 387a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar elif self.useReturn: 388a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S = 0 389a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar for i in range(1,self.maxSize+1+1): 390a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S += self.typeGen.cardinality ** i 391a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 392a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S = 0 393a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar for i in range(self.maxSize+1): 394a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar S += self.typeGen.cardinality ** i 395a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.cardinality = S 396a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 397a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def generateType(self, N): 398a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if self.useReturn: 399a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar # Skip the empty tuple 400a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar argIndices = getNthTuple(N+1, self.maxSize+1, self.typeGen.cardinality) 401a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar retIndex,argIndices = argIndices[0],argIndices[1:] 402a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar retTy = self.typeGen.get(retIndex) 403a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 404a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar retTy = None 405a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar argIndices = getNthTuple(N, self.maxSize, self.typeGen.cardinality) 406a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar args = map(self.typeGen.get, argIndices) 407a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return FunctionType(N, retTy, args) 408a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 409a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass AnyTypeGenerator(TypeGenerator): 410a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def __init__(self): 411a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar TypeGenerator.__init__(self) 412a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.generators = [] 413a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.bounds = [] 414a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.setCardinality() 415a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self._cardinality = None 416a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 417a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def getCardinality(self): 418a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if self._cardinality is None: 419a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return aleph0 420a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 421a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return self._cardinality 422a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def setCardinality(self): 423a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.bounds = [g.cardinality for g in self.generators] 424a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self._cardinality = sum(self.bounds) 425a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar cardinality = property(getCardinality, None) 426a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 427a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def addGenerator(self, g): 428a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.generators.append(g) 429a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar for i in range(100): 430a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar prev = self._cardinality 431a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self._cardinality = None 432a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar for g in self.generators: 433a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar g.setCardinality() 434a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar self.setCardinality() 435a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar if (self._cardinality is aleph0) or prev==self._cardinality: 436a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar break 437a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar else: 438a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar raise RuntimeError,"Infinite loop in setting cardinality" 439a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 440a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar def generateType(self, N): 441a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar index,M = getNthPairVariableBounds(N, self.bounds) 442a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar return self.generators[index].get(M) 443a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 444a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbardef test(): 44598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar fbtg = FixedTypeGenerator([BuiltinType('char', 4), 44698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar BuiltinType('char', 4, 0), 44798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar BuiltinType('int', 4, 5)]) 44898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar 44998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar fields1 = AnyTypeGenerator() 45098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar fields1.addGenerator( fbtg ) 45198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar 45298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar fields0 = AnyTypeGenerator() 45398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar fields0.addGenerator( fbtg ) 45498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar# fields0.addGenerator( RecordTypeGenerator(fields1, False, 4) ) 45598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar 45698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar btg = FixedTypeGenerator([BuiltinType('char', 4), 45798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar BuiltinType('int', 4)]) 45843ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor etg = EnumTypeGenerator([None, '-1', '1', '1u'], 0, 3) 45943ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor 460a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar atg = AnyTypeGenerator() 461a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar atg.addGenerator( btg ) 46298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar atg.addGenerator( RecordTypeGenerator(fields0, False, 4) ) 46343ec96da71b94f064ed6a3031025208d23acd592Douglas Gregor atg.addGenerator( etg ) 464a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar print 'Cardinality:',atg.cardinality 465a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar for i in range(100): 46698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar if i == atg.cardinality: 46798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar try: 46898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar atg.get(i) 46998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar raise RuntimeError,"Cardinality was wrong" 47098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar except AssertionError: 47198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar break 472a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar print '%4d: %s'%(i, atg.get(i)) 473a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar 474a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarif __name__ == '__main__': 475a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar test() 476