TypeGen.py revision 789e4babc9cf78df9565f215a119acad291aea63
1a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar"""Flexible enumeration of C types."""
2a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
3a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarfrom Enumeration import *
4a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
5a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar# TODO:
6a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
7a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar#  - struct improvements (bitfields, 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
13a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
14a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar###
15a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar# Actual type types
16a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
17a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass BuiltinType:
18789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar    def __init__(self, name, size):
19a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.name = name
20789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar        self.size = size
21789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar
22789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar    def sizeof(self):
23789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar        return self.size
24a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
25a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __str__(self):
26a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return self.name
27a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
28a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass RecordType:
29a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, index, isUnion, fields):
30a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.index = index
31a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.isUnion = isUnion
32a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.fields = fields
33a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.name = None
34a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
35a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __str__(self):
36a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return '%s { %s }'%(('struct','union')[self.isUnion],
37a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                            ' '.join(['%s;'%f for f in self.fields]))
38a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
39a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getTypedefDef(self, name, printer):
40a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        fields = ['%s field%d;'%(printer.getTypeName(t),i) for i,t in enumerate(self.fields)]
41a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        # Name the struct for more readable LLVM IR.
42a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return 'typedef %s %s { %s } %s;'%(('struct','union')[self.isUnion],
43a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                                           name, ' '.join(fields), name)
44a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
45a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass ArrayType:
46a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, index, isVector, elementType, size):
47a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if isVector:
48a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            # Note that for vectors, this is the size in bytes.
49a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            assert size > 0
50a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
51a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            assert size is None or size >= 0
52a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.index = index
53a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.isVector = isVector
54a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.elementType = elementType
55a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.size = size
56789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar        if isVector:
57789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar            eltSize = self.elementType.sizeof()
58789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar            assert not (self.size % eltSize)
59789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar            self.numElements = self.size // eltSize
60789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar        else:
61789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar            self.numElements = self.size
62a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
63a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __str__(self):
64a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.isVector:
65a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return 'vector (%s)[%d]'%(self.elementType,self.size)
66a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        elif self.size is not None:
67a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return '(%s)[%d]'%(self.elementType,self.size)
68a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
69a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return '(%s)[]'%(self.elementType,)
70a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
71a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getTypedefDef(self, name, printer):
72a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        elementName = printer.getTypeName(self.elementType)
73a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.isVector:
74a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return 'typedef %s %s __attribute__ ((vector_size (%d)));'%(elementName,
75a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                                                                        name,
76a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                                                                        self.size)
77a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
78a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if self.size is None:
79a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                sizeStr = ''
80a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            else:
81a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                sizeStr = str(self.size)
82a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return 'typedef %s %s[%s];'%(elementName, name, sizeStr)
83a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
84a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass ComplexType:
85a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, index, elementType):
86a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.index = index
87a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.elementType = elementType
88a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
89a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __str__(self):
90a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return '_Complex (%s)'%(self.elementType)
91a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
92a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getTypedefDef(self, name, printer):
93a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return 'typedef _Complex %s %s;'%(printer.getTypeName(self.elementType), name)
94a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
95a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass FunctionType:
96a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, index, returnType, argTypes):
97a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.index = index
98a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.returnType = returnType
99a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.argTypes = argTypes
100a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
101a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __str__(self):
102a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.returnType is None:
103a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            rt = 'void'
104a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
105a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            rt = str(self.returnType)
106a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if not self.argTypes:
107a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            at = 'void'
108a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
109a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            at = ', '.join(map(str, self.argTypes))
110a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return '%s (*)(%s)'%(rt, at)
111a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
112a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getTypedefDef(self, name, printer):
113a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.returnType is None:
114a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            rt = 'void'
115a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
116a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            rt = str(self.returnType)
117a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if not self.argTypes:
118a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            at = 'void'
119a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
120a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            at = ', '.join(map(str, self.argTypes))
121a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return 'typedef %s (*%s)(%s);'%(rt, name, at)
122a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
123a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar###
124a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar# Type enumerators
125a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
126a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass TypeGenerator(object):
127a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self):
128a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cache = {}
129a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
130a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
131a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        abstract
132a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
133a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def get(self, N):
134a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        T = self.cache.get(N)
135a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if T is None:
136a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            assert 0 <= N < self.cardinality
137a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            T = self.cache[N] = self.generateType(N)
138a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return T
139a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
140a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
141a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        abstract
142a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
143a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass FixedTypeGenerator(TypeGenerator):
144a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, types):
145a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
146a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.types = types
147a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
148a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
149a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
150a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = len(self.types)
151a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
152a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
153a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return self.types[N]
154a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
155a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass ComplexTypeGenerator(TypeGenerator):
156a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, typeGen):
157a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
158a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.typeGen = typeGen
159a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
160a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
161a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
162a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = self.typeGen.cardinality
163a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
164a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
165a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return ComplexType(N, self.typeGen.get(N))
166a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
167a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass VectorTypeGenerator(TypeGenerator):
168a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, typeGen, sizes):
169a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
170a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.typeGen = typeGen
171a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.sizes = tuple(map(int,sizes))
172a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
173a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
174a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
175a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = len(self.sizes)*self.typeGen.cardinality
176a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
177a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
178a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality)
179a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return ArrayType(N, True, self.typeGen.get(T), self.sizes[S])
180a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
181a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass FixedArrayTypeGenerator(TypeGenerator):
182a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, typeGen, sizes):
183a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
184a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.typeGen = typeGen
185a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.sizes = tuple(size)
186a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
187a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
188a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
189a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = len(self.sizes)*self.typeGen.cardinality
190a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
191a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
192a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality)
193a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return ArrayType(N, false, self.typeGen.get(T), self.sizes[S])
194a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
195a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass ArrayTypeGenerator(TypeGenerator):
196a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, typeGen, maxSize, useIncomplete=False, useZero=False):
197a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
198a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.typeGen = typeGen
199a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.useIncomplete = useIncomplete
200a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.useZero = useZero
201a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.maxSize = int(maxSize)
202a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.W = useIncomplete + useZero + self.maxSize
203a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
204a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
205a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
206a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = self.W * self.typeGen.cardinality
207a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
208a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
209a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        S,T = getNthPairBounded(N, self.W, self.typeGen.cardinality)
210a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.useIncomplete:
211a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if S==0:
212a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                size = None
213a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                S = None
214a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            else:
215a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                S = S - 1
216a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if S is not None:
217a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if self.useZero:
218a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                size = S
219a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            else:
220a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                size = S + 1
221a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return ArrayType(N, False, self.typeGen.get(T), size)
222a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
223a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass RecordTypeGenerator(TypeGenerator):
224a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, typeGen, useUnion, maxSize):
225a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
226a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.typeGen = typeGen
227a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.useUnion = bool(useUnion)
228a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.maxSize = int(maxSize)
229a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
230a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
231a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
232a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        M = 1 + self.useUnion
233a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.maxSize is aleph0:
234a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            S =  aleph0 * self.typeGen.cardinality
235a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
236a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            S = 0
237a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for i in range(self.maxSize+1):
238a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                S += M * (self.typeGen.cardinality ** i)
239a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = S
240a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
241a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
242a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        isUnion,I = False,N
243a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.useUnion:
244a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            isUnion,I = (I&1),I>>1
245a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        fields = map(self.typeGen.get,getNthTuple(I,self.maxSize,self.typeGen.cardinality))
246a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return RecordType(N, isUnion, fields)
247a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
248a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass FunctionTypeGenerator(TypeGenerator):
249a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self, typeGen, useReturn, maxSize):
250a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
251a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.typeGen = typeGen
252a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.useReturn = useReturn
253a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.maxSize = maxSize
254a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
255a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
256a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
257a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.maxSize is aleph0:
258a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            S = aleph0 * self.typeGen.cardinality()
259a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        elif self.useReturn:
260a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            S = 0
261a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for i in range(1,self.maxSize+1+1):
262a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                S += self.typeGen.cardinality ** i
263a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
264a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            S = 0
265a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for i in range(self.maxSize+1):
266a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                S += self.typeGen.cardinality ** i
267a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.cardinality = S
268a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
269a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
270a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self.useReturn:
271a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            # Skip the empty tuple
272a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            argIndices = getNthTuple(N+1, self.maxSize+1, self.typeGen.cardinality)
273a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            retIndex,argIndices = argIndices[0],argIndices[1:]
274a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            retTy = self.typeGen.get(retIndex)
275a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
276a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            retTy = None
277a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            argIndices = getNthTuple(N, self.maxSize, self.typeGen.cardinality)
278a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        args = map(self.typeGen.get, argIndices)
279a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return FunctionType(N, retTy, args)
280a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
281a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarclass AnyTypeGenerator(TypeGenerator):
282a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def __init__(self):
283a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        TypeGenerator.__init__(self)
284a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.generators = []
285a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.bounds = []
286a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.setCardinality()
287a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self._cardinality = None
288a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
289a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def getCardinality(self):
290a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        if self._cardinality is None:
291a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return aleph0
292a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
293a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            return self._cardinality
294a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def setCardinality(self):
295a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.bounds = [g.cardinality for g in self.generators]
296a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self._cardinality = sum(self.bounds)
297a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    cardinality = property(getCardinality, None)
298a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
299a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def addGenerator(self, g):
300a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        self.generators.append(g)
301a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        for i in range(100):
302a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            prev = self._cardinality
303a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            self._cardinality = None
304a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            for g in self.generators:
305a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                g.setCardinality()
306a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            self.setCardinality()
307a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            if (self._cardinality is aleph0) or prev==self._cardinality:
308a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar                break
309a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        else:
310a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar            raise RuntimeError,"Infinite loop in setting cardinality"
311a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
312a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    def generateType(self, N):
313a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        index,M = getNthPairVariableBounds(N, self.bounds)
314a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        return self.generators[index].get(M)
315a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
316a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbardef test():
317a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    atg = AnyTypeGenerator()
318789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar    btg = FixedTypeGenerator([BuiltinType('int',4),
319789e4babc9cf78df9565f215a119acad291aea63Daniel Dunbar                              BuiltinType('float',4)])
320a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    atg.addGenerator( btg )
321a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    atg.addGenerator( ComplexTypeGenerator(btg) )
322a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    atg.addGenerator( RecordTypeGenerator(atg, True, 2) )
323a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    atg.addGenerator( VectorTypeGenerator(btg, (4,8)) )
324a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    atg.addGenerator( ArrayTypeGenerator(btg, 4) )
325a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    atg.addGenerator( FunctionTypeGenerator(btg, False, 2) )
326a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    print 'Cardinality:',atg.cardinality
327a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    for i in range(100):
328a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar        print '%4d: %s'%(i, atg.get(i))
329a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar
330a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbarif __name__ == '__main__':
331a1bfe638c03c517b110f55962adb882f47131667Daniel Dunbar    test()
332