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