TypeGen.py revision 98cca78ecd75704998eea81031bb82f06a9ed5de
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
2798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbarclass BuiltinType(Type):
2898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    def __init__(self, name, size, bitFieldSize=None):
29a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.name = name
30789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar        self.size = size
3198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        self.bitFieldSize = bitFieldSize
3298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar
3398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    def isBitField(self):
3498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        return self.bitFieldSize is not None
3598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar
3698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    def isPaddingBitField(self):
3798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        return self.bitFieldSize is 0
3898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar
3998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    def getBitFieldSize(self):
4098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        assert self.isBitField()
4198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        return self.bitFieldSize
42789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar
43789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar    def sizeof(self):
44789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar        return self.size
45a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
46a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __str__(self):
47a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return self.name
48a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
4998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbarclass RecordType(Type):
50a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, index, isUnion, fields):
51a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.index = index
52a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.isUnion = isUnion
53a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.fields = fields
54a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.name = None
55a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
5698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    def __str__(self):
5798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        def getField(t):
5898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            if t.isBitField():
5998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                return "%s : %d;" % (t, t.getBitFieldSize())
6098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            else:
6198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                return "%s;" % t
6298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar
63a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return '%s { %s }'%(('struct','union')[self.isUnion],
6498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                            ' '.join(map(getField, self.fields)))
65a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
66a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getTypedefDef(self, name, printer):
6798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        def getField((i, t)):
6898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            if t.isBitField():
6998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                if t.isPaddingBitField():
7098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                    return '%s : 0;'%(printer.getTypeName(t),)
7198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                else:
7298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                    return '%s field%d : %d;'%(printer.getTypeName(t),i,
7398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                                               t.getBitFieldSize())
7498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            else:
7598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                return '%s field%d;'%(printer.getTypeName(t),i)
7698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        fields = map(getField, enumerate(self.fields))
77a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        # Name the struct for more readable LLVM IR.
78a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return 'typedef %s %s { %s } %s;'%(('struct','union')[self.isUnion],
79a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                                           name, ' '.join(fields), name)
80a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
8198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbarclass ArrayType(Type):
82a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, index, isVector, elementType, size):
83a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if isVector:
84a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            # Note that for vectors, this is the size in bytes.
85a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            assert size > 0
86a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
87a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            assert size is None or size >= 0
88a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.index = index
89a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.isVector = isVector
90a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.elementType = elementType
91a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.size = size
92789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar        if isVector:
93789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar            eltSize = self.elementType.sizeof()
94789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar            assert not (self.size % eltSize)
95789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar            self.numElements = self.size // eltSize
96789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar        else:
97789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar            self.numElements = self.size
98a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
99a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __str__(self):
100a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.isVector:
101a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return 'vector (%s)[%d]'%(self.elementType,self.size)
102a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        elif self.size is not None:
103a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return '(%s)[%d]'%(self.elementType,self.size)
104a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
105a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return '(%s)[]'%(self.elementType,)
106a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
107a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getTypedefDef(self, name, printer):
108a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        elementName = printer.getTypeName(self.elementType)
109a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.isVector:
110a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return 'typedef %s %s __attribute__ ((vector_size (%d)));'%(elementName,
111a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                                                                        name,
112a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                                                                        self.size)
113a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
114a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if self.size is None:
115a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                sizeStr = ''
116a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            else:
117a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                sizeStr = str(self.size)
118a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return 'typedef %s %s[%s];'%(elementName, name, sizeStr)
119a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
12098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbarclass ComplexType(Type):
121a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, index, elementType):
122a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.index = index
123a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.elementType = elementType
124a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
125a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __str__(self):
126a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return '_Complex (%s)'%(self.elementType)
127a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
128a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getTypedefDef(self, name, printer):
129a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return 'typedef _Complex %s %s;'%(printer.getTypeName(self.elementType), name)
130a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
13198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbarclass FunctionType(Type):
132a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, index, returnType, argTypes):
133a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.index = index
134a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.returnType = returnType
135a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.argTypes = argTypes
136a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
137a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __str__(self):
138a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.returnType is None:
139a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            rt = 'void'
140a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
141a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            rt = str(self.returnType)
142a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if not self.argTypes:
143a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            at = 'void'
144a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
145a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            at = ', '.join(map(str, self.argTypes))
146a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return '%s (*)(%s)'%(rt, at)
147a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
148a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getTypedefDef(self, name, printer):
149a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.returnType is None:
150a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            rt = 'void'
151a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
152a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            rt = str(self.returnType)
153a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if not self.argTypes:
154a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            at = 'void'
155a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
156a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            at = ', '.join(map(str, self.argTypes))
157a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return 'typedef %s (*%s)(%s);'%(rt, name, at)
158a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
159a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar###
160a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar# Type enumerators
161a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
162a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass TypeGenerator(object):
163a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self):
164a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cache = {}
165a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
166a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
167a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        abstract
168a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
169a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def get(self, N):
170a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        T = self.cache.get(N)
171a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if T is None:
172a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            assert 0 <= N < self.cardinality
173a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            T = self.cache[N] = self.generateType(N)
174a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return T
175a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
176a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
177a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        abstract
178a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
179a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass FixedTypeGenerator(TypeGenerator):
180a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, types):
181a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
182a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.types = types
183a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
184a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
185a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
186a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = len(self.types)
187a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
188a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
189a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return self.types[N]
190a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
191a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass ComplexTypeGenerator(TypeGenerator):
192a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, typeGen):
193a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
194a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.typeGen = typeGen
195a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
196a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
197a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
198a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = self.typeGen.cardinality
199a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
200a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
201a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return ComplexType(N, self.typeGen.get(N))
202a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
203a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass VectorTypeGenerator(TypeGenerator):
204a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, typeGen, sizes):
205a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
206a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.typeGen = typeGen
207a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.sizes = tuple(map(int,sizes))
208a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
209a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
210a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
211a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = len(self.sizes)*self.typeGen.cardinality
212a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
213a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
214a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality)
215a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return ArrayType(N, True, self.typeGen.get(T), self.sizes[S])
216a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
217a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass FixedArrayTypeGenerator(TypeGenerator):
218a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, typeGen, sizes):
219a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
220a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.typeGen = typeGen
221a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.sizes = tuple(size)
222a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
223a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
224a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
225a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = len(self.sizes)*self.typeGen.cardinality
226a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
227a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
228a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality)
229a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return ArrayType(N, false, self.typeGen.get(T), self.sizes[S])
230a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
231a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass ArrayTypeGenerator(TypeGenerator):
232a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, typeGen, maxSize, useIncomplete=False, useZero=False):
233a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
234a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.typeGen = typeGen
235a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.useIncomplete = useIncomplete
236a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.useZero = useZero
237a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.maxSize = int(maxSize)
238a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.W = useIncomplete + useZero + self.maxSize
239a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
240a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
241a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
242a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = self.W * self.typeGen.cardinality
243a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
244a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
245a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        S,T = getNthPairBounded(N, self.W, self.typeGen.cardinality)
246a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.useIncomplete:
247a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if S==0:
248a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                size = None
249a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                S = None
250a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            else:
251a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                S = S - 1
252a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if S is not None:
253a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if self.useZero:
254a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                size = S
255a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            else:
256a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                size = S + 1
257a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return ArrayType(N, False, self.typeGen.get(T), size)
258a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
259a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass RecordTypeGenerator(TypeGenerator):
260a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, typeGen, useUnion, maxSize):
261a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
262a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.typeGen = typeGen
263a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.useUnion = bool(useUnion)
264a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.maxSize = int(maxSize)
265a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
266a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
267a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
268a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        M = 1 + self.useUnion
269a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.maxSize is aleph0:
270a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            S =  aleph0 * self.typeGen.cardinality
271a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
272a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            S = 0
273a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for i in range(self.maxSize+1):
274a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                S += M * (self.typeGen.cardinality ** i)
275a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = S
276a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
277a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
278a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        isUnion,I = False,N
279a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.useUnion:
280a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            isUnion,I = (I&1),I>>1
281a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        fields = map(self.typeGen.get,getNthTuple(I,self.maxSize,self.typeGen.cardinality))
282a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return RecordType(N, isUnion, fields)
283a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
284a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass FunctionTypeGenerator(TypeGenerator):
285a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, typeGen, useReturn, maxSize):
286a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
287a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.typeGen = typeGen
288a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.useReturn = useReturn
289a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.maxSize = maxSize
290a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
291a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
292a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
293a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.maxSize is aleph0:
294a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            S = aleph0 * self.typeGen.cardinality()
295a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        elif self.useReturn:
296a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            S = 0
297a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for i in range(1,self.maxSize+1+1):
298a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                S += self.typeGen.cardinality ** i
299a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
300a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            S = 0
301a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for i in range(self.maxSize+1):
302a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                S += self.typeGen.cardinality ** i
303a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = S
304a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
305a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
306a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.useReturn:
307a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            # Skip the empty tuple
308a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            argIndices = getNthTuple(N+1, self.maxSize+1, self.typeGen.cardinality)
309a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            retIndex,argIndices = argIndices[0],argIndices[1:]
310a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            retTy = self.typeGen.get(retIndex)
311a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
312a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            retTy = None
313a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            argIndices = getNthTuple(N, self.maxSize, self.typeGen.cardinality)
314a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        args = map(self.typeGen.get, argIndices)
315a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return FunctionType(N, retTy, args)
316a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
317a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass AnyTypeGenerator(TypeGenerator):
318a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self):
319a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
320a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.generators = []
321a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.bounds = []
322a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
323a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self._cardinality = None
324a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
325a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getCardinality(self):
326a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self._cardinality is None:
327a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return aleph0
328a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
329a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return self._cardinality
330a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
331a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.bounds = [g.cardinality for g in self.generators]
332a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self._cardinality = sum(self.bounds)
333a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    cardinality = property(getCardinality, None)
334a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
335a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def addGenerator(self, g):
336a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.generators.append(g)
337a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        for i in range(100):
338a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            prev = self._cardinality
339a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            self._cardinality = None
340a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for g in self.generators:
341a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                g.setCardinality()
342a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            self.setCardinality()
343a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if (self._cardinality is aleph0) or prev==self._cardinality:
344a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                break
345a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
346a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            raise RuntimeError,"Infinite loop in setting cardinality"
347a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
348a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
349a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        index,M = getNthPairVariableBounds(N, self.bounds)
350a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return self.generators[index].get(M)
351a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
352a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbardef test():
35398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    fbtg = FixedTypeGenerator([BuiltinType('char', 4),
35498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                               BuiltinType('char', 4, 0),
35598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                               BuiltinType('int',  4, 5)])
35698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar
35798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    fields1 = AnyTypeGenerator()
35898cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    fields1.addGenerator( fbtg )
35998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar
36098cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    fields0 = AnyTypeGenerator()
36198cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    fields0.addGenerator( fbtg )
36298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar#    fields0.addGenerator( RecordTypeGenerator(fields1, False, 4) )
36398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar
36498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    btg = FixedTypeGenerator([BuiltinType('char', 4),
36598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                              BuiltinType('int',  4)])
36698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar
367a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    atg = AnyTypeGenerator()
368a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    atg.addGenerator( btg )
36998cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar    atg.addGenerator( RecordTypeGenerator(fields0, False, 4) )
370a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    print 'Cardinality:',atg.cardinality
371a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    for i in range(100):
37298cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar        if i == atg.cardinality:
37398cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            try:
37498cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                atg.get(i)
37598cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                raise RuntimeError,"Cardinality was wrong"
37698cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar            except AssertionError:
37798cca78ecd75704998eea81031bb82f06a9ed5deDaniel Dunbar                break
378a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        print '%4d: %s'%(i, atg.get(i))
379a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
380a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarif __name__ == '__main__':
381a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    test()
382