"""Flexible enumeration of C types."""

from Enumeration import *

# TODO:

#  - struct improvements (flexible arrays, packed &
#    unpacked, alignment)
#  - objective-c qualified id
#  - anonymous / transparent unions
#  - VLAs
#  - block types
#  - K&R functions
#  - pass arguments of different types (test extension, transparent union)
#  - varargs

###
# Actual type types

class Type:
    def isBitField(self):
        return False

    def isPaddingBitField(self):
        return False

    def getTypeName(self, printer):
        name = 'T%d' % len(printer.types)
        typedef = self.getTypedefDef(name, printer)
        printer.addDeclaration(typedef)
        return name

class BuiltinType(Type):
    def __init__(self, name, size, bitFieldSize=None):
        self.name = name
        self.size = size
        self.bitFieldSize = bitFieldSize

    def isBitField(self):
        return self.bitFieldSize is not None

    def isPaddingBitField(self):
        return self.bitFieldSize is 0

    def getBitFieldSize(self):
        assert self.isBitField()
        return self.bitFieldSize

    def getTypeName(self, printer):
        return self.name

    def sizeof(self):
        return self.size

    def __str__(self):
        return self.name

class EnumType(Type):
    unique_id = 0

    def __init__(self, index, enumerators):
        self.index = index
        self.enumerators = enumerators
        self.unique_id = self.__class__.unique_id
        self.__class__.unique_id += 1

    def getEnumerators(self):
        result = ''
        for i, init in enumerate(self.enumerators):
            if i > 0:
                result = result + ', '
            result = result + 'enum%dval%d_%d' % (self.index, i, self.unique_id)
            if init:
                result = result + ' = %s' % (init)

        return result

    def __str__(self):
        return 'enum { %s }' % (self.getEnumerators())

    def getTypedefDef(self, name, printer):
        return 'typedef enum %s { %s } %s;'%(name, self.getEnumerators(), name)

class RecordType(Type):
    def __init__(self, index, isUnion, fields):
        self.index = index
        self.isUnion = isUnion
        self.fields = fields
        self.name = None

    def __str__(self):
        def getField(t):
            if t.isBitField():
                return "%s : %d;" % (t, t.getBitFieldSize())
            else:
                return "%s;" % t

        return '%s { %s }'%(('struct','union')[self.isUnion],
                            ' '.join(map(getField, self.fields)))

    def getTypedefDef(self, name, printer):
        def getField((i, t)):
            if t.isBitField():
                if t.isPaddingBitField():
                    return '%s : 0;'%(printer.getTypeName(t),)
                else:
                    return '%s field%d : %d;'%(printer.getTypeName(t),i,
                                               t.getBitFieldSize())
            else:
                return '%s field%d;'%(printer.getTypeName(t),i)
        fields = map(getField, enumerate(self.fields))
        # Name the struct for more readable LLVM IR.
        return 'typedef %s %s { %s } %s;'%(('struct','union')[self.isUnion],
                                           name, ' '.join(fields), name)
                                           
class ArrayType(Type):
    def __init__(self, index, isVector, elementType, size):
        if isVector:
            # Note that for vectors, this is the size in bytes.
            assert size > 0
        else:
            assert size is None or size >= 0
        self.index = index
        self.isVector = isVector
        self.elementType = elementType
        self.size = size
        if isVector:
            eltSize = self.elementType.sizeof()
            assert not (self.size % eltSize)
            self.numElements = self.size // eltSize
        else:
            self.numElements = self.size

    def __str__(self):
        if self.isVector:
            return 'vector (%s)[%d]'%(self.elementType,self.size)
        elif self.size is not None:
            return '(%s)[%d]'%(self.elementType,self.size)
        else:
            return '(%s)[]'%(self.elementType,)

    def getTypedefDef(self, name, printer):
        elementName = printer.getTypeName(self.elementType)
        if self.isVector:
            return 'typedef %s %s __attribute__ ((vector_size (%d)));'%(elementName,
                                                                        name,
                                                                        self.size)
        else:
            if self.size is None:
                sizeStr = ''
            else:
                sizeStr = str(self.size)
            return 'typedef %s %s[%s];'%(elementName, name, sizeStr)

class ComplexType(Type):
    def __init__(self, index, elementType):
        self.index = index
        self.elementType = elementType

    def __str__(self):
        return '_Complex (%s)'%(self.elementType)

    def getTypedefDef(self, name, printer):
        return 'typedef _Complex %s %s;'%(printer.getTypeName(self.elementType), name)

class FunctionType(Type):
    def __init__(self, index, returnType, argTypes):
        self.index = index
        self.returnType = returnType
        self.argTypes = argTypes

    def __str__(self):
        if self.returnType is None:
            rt = 'void'
        else:
            rt = str(self.returnType)
        if not self.argTypes:
            at = 'void'
        else:
            at = ', '.join(map(str, self.argTypes))
        return '%s (*)(%s)'%(rt, at)

    def getTypedefDef(self, name, printer):
        if self.returnType is None:
            rt = 'void'
        else:
            rt = str(self.returnType)
        if not self.argTypes:
            at = 'void'
        else:
            at = ', '.join(map(str, self.argTypes))
        return 'typedef %s (*%s)(%s);'%(rt, name, at)

###
# Type enumerators

class TypeGenerator(object):
    def __init__(self):
        self.cache = {}

    def setCardinality(self):
        abstract

    def get(self, N):
        T = self.cache.get(N)
        if T is None:
            assert 0 <= N < self.cardinality
            T = self.cache[N] = self.generateType(N)
        return T

    def generateType(self, N):
        abstract

class FixedTypeGenerator(TypeGenerator):
    def __init__(self, types):
        TypeGenerator.__init__(self)
        self.types = types
        self.setCardinality()

    def setCardinality(self):
        self.cardinality = len(self.types)

    def generateType(self, N):
        return self.types[N]

# Factorial
def fact(n):
    result = 1
    while n > 0:
        result = result * n
        n = n - 1
    return result

# Compute the number of combinations (n choose k)
def num_combinations(n, k): 
    return fact(n) / (fact(k) * fact(n - k))

# Enumerate the combinations choosing k elements from the list of values
def combinations(values, k):
    # From ActiveState Recipe 190465: Generator for permutations,
    # combinations, selections of a sequence
    if k==0: yield []
    else:
        for i in xrange(len(values)-k+1):
            for cc in combinations(values[i+1:],k-1):
                yield [values[i]]+cc

class EnumTypeGenerator(TypeGenerator):
    def __init__(self, values, minEnumerators, maxEnumerators):
        TypeGenerator.__init__(self)
        self.values = values
        self.minEnumerators = minEnumerators
        self.maxEnumerators = maxEnumerators
        self.setCardinality()

    def setCardinality(self):
        self.cardinality = 0
        for num in range(self.minEnumerators, self.maxEnumerators + 1):
            self.cardinality += num_combinations(len(self.values), num)

    def generateType(self, n):
        # Figure out the number of enumerators in this type
        numEnumerators = self.minEnumerators
        valuesCovered = 0
        while numEnumerators < self.maxEnumerators:
            comb = num_combinations(len(self.values), numEnumerators)
            if valuesCovered + comb > n:
                break
            numEnumerators = numEnumerators + 1
            valuesCovered += comb

        # Find the requested combination of enumerators and build a
        # type from it.
        i = 0
        for enumerators in combinations(self.values, numEnumerators):
            if i == n - valuesCovered:
                return EnumType(n, enumerators)
                
            i = i + 1

        assert False

class ComplexTypeGenerator(TypeGenerator):
    def __init__(self, typeGen):
        TypeGenerator.__init__(self)
        self.typeGen = typeGen
        self.setCardinality()
    
    def setCardinality(self):
        self.cardinality = self.typeGen.cardinality

    def generateType(self, N):
        return ComplexType(N, self.typeGen.get(N))

class VectorTypeGenerator(TypeGenerator):
    def __init__(self, typeGen, sizes):
        TypeGenerator.__init__(self)
        self.typeGen = typeGen
        self.sizes = tuple(map(int,sizes))
        self.setCardinality()

    def setCardinality(self):
        self.cardinality = len(self.sizes)*self.typeGen.cardinality

    def generateType(self, N):
        S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality)
        return ArrayType(N, True, self.typeGen.get(T), self.sizes[S])

class FixedArrayTypeGenerator(TypeGenerator):
    def __init__(self, typeGen, sizes):
        TypeGenerator.__init__(self)
        self.typeGen = typeGen
        self.sizes = tuple(size)
        self.setCardinality()

    def setCardinality(self):
        self.cardinality = len(self.sizes)*self.typeGen.cardinality

    def generateType(self, N):
        S,T = getNthPairBounded(N, len(self.sizes), self.typeGen.cardinality)
        return ArrayType(N, false, self.typeGen.get(T), self.sizes[S])

class ArrayTypeGenerator(TypeGenerator):
    def __init__(self, typeGen, maxSize, useIncomplete=False, useZero=False):
        TypeGenerator.__init__(self)
        self.typeGen = typeGen
        self.useIncomplete = useIncomplete
        self.useZero = useZero
        self.maxSize = int(maxSize)
        self.W = useIncomplete + useZero + self.maxSize
        self.setCardinality()

    def setCardinality(self):
        self.cardinality = self.W * self.typeGen.cardinality

    def generateType(self, N):
        S,T = getNthPairBounded(N, self.W, self.typeGen.cardinality)
        if self.useIncomplete:
            if S==0:
                size = None
                S = None
            else:
                S = S - 1
        if S is not None:
            if self.useZero:
                size = S
            else:
                size = S + 1        
        return ArrayType(N, False, self.typeGen.get(T), size)

class RecordTypeGenerator(TypeGenerator):
    def __init__(self, typeGen, useUnion, maxSize):
        TypeGenerator.__init__(self)
        self.typeGen = typeGen
        self.useUnion = bool(useUnion)
        self.maxSize = int(maxSize)
        self.setCardinality()

    def setCardinality(self):
        M = 1 + self.useUnion
        if self.maxSize is aleph0:
            S =  aleph0 * self.typeGen.cardinality
        else:
            S = 0
            for i in range(self.maxSize+1):
                S += M * (self.typeGen.cardinality ** i)
        self.cardinality = S

    def generateType(self, N):
        isUnion,I = False,N
        if self.useUnion:
            isUnion,I = (I&1),I>>1
        fields = map(self.typeGen.get,getNthTuple(I,self.maxSize,self.typeGen.cardinality))
        return RecordType(N, isUnion, fields)

class FunctionTypeGenerator(TypeGenerator):
    def __init__(self, typeGen, useReturn, maxSize):
        TypeGenerator.__init__(self)
        self.typeGen = typeGen
        self.useReturn = useReturn
        self.maxSize = maxSize
        self.setCardinality()
    
    def setCardinality(self):
        if self.maxSize is aleph0:
            S = aleph0 * self.typeGen.cardinality()
        elif self.useReturn:
            S = 0
            for i in range(1,self.maxSize+1+1):
                S += self.typeGen.cardinality ** i
        else:
            S = 0
            for i in range(self.maxSize+1):
                S += self.typeGen.cardinality ** i
        self.cardinality = S
    
    def generateType(self, N):
        if self.useReturn:
            # Skip the empty tuple
            argIndices = getNthTuple(N+1, self.maxSize+1, self.typeGen.cardinality)
            retIndex,argIndices = argIndices[0],argIndices[1:]
            retTy = self.typeGen.get(retIndex)
        else:
            retTy = None
            argIndices = getNthTuple(N, self.maxSize, self.typeGen.cardinality)
        args = map(self.typeGen.get, argIndices)
        return FunctionType(N, retTy, args)

class AnyTypeGenerator(TypeGenerator):
    def __init__(self):
        TypeGenerator.__init__(self)
        self.generators = []
        self.bounds = []
        self.setCardinality()
        self._cardinality = None
        
    def getCardinality(self):
        if self._cardinality is None:
            return aleph0
        else:
            return self._cardinality
    def setCardinality(self):
        self.bounds = [g.cardinality for g in self.generators]
        self._cardinality = sum(self.bounds)
    cardinality = property(getCardinality, None)

    def addGenerator(self, g):
        self.generators.append(g)
        for i in range(100):
            prev = self._cardinality
            self._cardinality = None
            for g in self.generators:
                g.setCardinality()
            self.setCardinality()
            if (self._cardinality is aleph0) or prev==self._cardinality:
                break
        else:
            raise RuntimeError,"Infinite loop in setting cardinality"

    def generateType(self, N):
        index,M = getNthPairVariableBounds(N, self.bounds)
        return self.generators[index].get(M)

def test():
    fbtg = FixedTypeGenerator([BuiltinType('char', 4),
                               BuiltinType('char', 4, 0),
                               BuiltinType('int',  4, 5)])

    fields1 = AnyTypeGenerator()
    fields1.addGenerator( fbtg )

    fields0 = AnyTypeGenerator()
    fields0.addGenerator( fbtg )
#    fields0.addGenerator( RecordTypeGenerator(fields1, False, 4) )

    btg = FixedTypeGenerator([BuiltinType('char', 4),
                              BuiltinType('int',  4)])
    etg = EnumTypeGenerator([None, '-1', '1', '1u'], 0, 3)

    atg = AnyTypeGenerator()
    atg.addGenerator( btg )
    atg.addGenerator( RecordTypeGenerator(fields0, False, 4) )
    atg.addGenerator( etg )
    print 'Cardinality:',atg.cardinality
    for i in range(100):
        if i == atg.cardinality:
            try:
                atg.get(i)
                raise RuntimeError,"Cardinality was wrong"
            except AssertionError:
                break
        print '%4d: %s'%(i, atg.get(i))

if __name__ == '__main__':
    test()
