Пример #1
0
 def __init__(self, compsym):
     self.compsym = compsym
     
     ordset = common.OrderedSet
     
     self.enumvars = ordset()
     self.enumlocals = ordset()
     self.enumparams = ordset()
     self.setparams = ordset()
     
     compnode = compsym.defnode.value
     
     posvars = set()
     negvars = set()
     
     # Check for bad patterns in enumerators.
     kinds = itertools.chain(*dka.findNodeTypes(compnode.enums))
     if dha.PatExpr in kinds or dha.PatIgnore in kinds:
         raise CompError('Invalid enumerator pattern')
     
     # Gather enumeration variables and iterated sets.
     for enum in compnode.enums:
         self.setparams.add(enum.iter)
         
         syms = st.gatherSymbols(enum.target)
         self.enumvars.update(syms)
         
         if dha.isPosEnum(enum):
             posvars.update(syms)
         else:
             negvars.update(syms)
     
     # Check that iterated sets are not enumeration variables.
     if set(self.setparams) & set(self.enumvars):
         raise CompError('Set parameters may not be enumeration variables')
     
     # Check safeness.
     if not negvars.issubset(posvars):
         raise CompError('Unsafe negation')
     
     # Check that result and condition expressions use only
     # enumeration variables.
     rescondvars = set()
     rescondvars.update(st.gatherSymbols(compnode.elt))
     rescondvars.update(itertools.chain(
         *(st.gatherSymbols(cond) for cond in compnode.conds)))
     
     if not rescondvars.issubset(self.enumvars):
         raise CompError('Invalid dependency on non-enum vars '
                         'in result or condition expression')
     
     # Separate locals from parameter enumvars.
     compscope = st.getNodeScope(compnode)
     for var in self.enumvars:
         if (compscope.immediateLookupSymbol(var.name, st.KIND_VSYM)
             is not None):
             self.enumlocals.add(var)
         else:
             self.enumparams.add(var)
Пример #2
0
 def helper(self, target, id):
     syms = st.gatherSymbols(target)
     
     newtarget = du.genDPatTuple([dha.PatVar(s, dha.P_UNKNOWN) for s in syms])
     
     # Generate wildcard comprehension.
     elt = du.genDTuple([dha.Name(s) for s in syms])
     enumtarget = dka.copy(target)
     st.cleanPatterns(enumtarget)
     WildcardFiller().run(enumtarget)
     enum = dha.RelEnum(enumtarget, id)
     comp = dha.RelSetComp(elt, [enum], [], dka.Symtab())
     
     num = next(wildcard_uid)
     
     repldict = {s: dha.VSymbol(s.name + '_W' + num)
                 for s in syms}
     st.replaceSymbols(comp, repldict)
     
     newid = dha.VSymbol(id.name + '_W' + num)
     
     invdef = dha.InvDef(newid, comp)
     
     ### Need a more robust way to do this part.
     oldccb = self.code_callback
     newccb = \
         (lambda ccb: oldccb(ccb) + [invdef]
             if ccb is self.CCB_NORMAL or
                ccb is self.CCB_LOOP_ENTRY
             else [])
     
     return newtarget, newid, newccb
Пример #3
0
def genTagInfo(comp):
    info = comp.info
    compnode = comp.getCompNode()
    
    uset = info.uset
    if uset is None:
        return
    
    enums = compnode.enums
    assert(enums[0].iter is uset)
    rootsyms = set(st.gatherSymbols(enums[0].target))
    unconsparams = info.unconsparams
    assert(rootsyms == set(unconsparams))
    
    taginfo = TagInfo()
    info.taginfo = taginfo
    taginfo.compinfo = info
    
    pairenums = enums[1:]
    
    taginfo.As = As = []
    taginfo.Bs = Bs = []
    taginfo.Rs = Rs = []
    taginfo.DRs = DRs = []
    
    for i, enum in enumerate(pairenums):
        dka.assertnodetype(enum.target, dha.PatTuple)
        elts = enum.target.elts
        assert(len(elts) == 2)
        dka.assertnodetype(elts[0], dha.PatVar)
        dka.assertnodetype(elts[1], dha.PatVar)
        
        cont, elem = elts[0].id, elts[1].id
        rel = enum.iter
        
        As.append(cont)
        Bs.append(elem)
        Rs.append(rel)
        
        demrel = TagSym('Dm_' + info.compsym.id + '_' + str(i+1))
        DRs.append(demrel)
    
    taginfo.tagcomps = tagcomps = []
    
    # Generate auxiliary demand comprehensions.
    for i, (a, b, r, dr) in enumerate(zip(As, Bs, Rs, DRs)):
        tagenums = []
        
        # Add U pred.
        if a in unconsparams:
            k = unconsparams.index(a)
            ig1 = [dha.PatIgnore() for z in range(0, i)]
            ig2 = [dha.PatIgnore() for z in range(i+1, len(unconsparams))]
            tup = du.genDPatTuple(ig1 + [dha.genUnboundVar(a)] + ig2)
            e = dha.Enum(tup, uset)
            tagenums.append(e)
        
        # Add other preds.
        for a2, b2, r2, dr2 in list(zip(As, Bs, Rs, DRs))[:i]:
            if b2 is a:
                tup = dha.PatTuple([dha.PatIgnore(), dha.genUnboundVar(b2)])
                e = dha.Enum(tup, dr2)
                tagenums.append(e)
        
        # Add orig relation.
        assert(len(tagenums) > 0)
        tup = dha.PatTuple([dha.genUnboundVar(a), dha.genUnboundVar(b)])
        e = dha.Enum(tup, r)
        tagenums.append(e)
        
        comp = dha.SetComp(dha.Tuple([dha.Name(a), dha.Name(b)]), tagenums,
                           None, dka.Symtab())
        
        instmapping = {s: dha.VSymbol(s.name + '_t' + str(i))
                       for s in set(As) | set(Bs)}
        st.replaceSymbols(comp, instmapping)
        
        compdef = dha.SetCompDef(dr, comp)
        tagcomps.append(compdef)
    
    return taginfo
Пример #4
0
def enumsToClauses_reordered(enums, cond, body, boundsyms):
    
    ENUM = 'ENUM'
    COND = 'COND'
    
    boundsyms = set(boundsyms)
    
    alltargetsyms = set()
    
    enum_list = []
    
    for e in enums:
        targetsyms = set(st.gatherSymbols(e.target))
        alltargetsyms |= targetsyms
        unboundsyms = targetsyms - boundsyms
        
        isfield = (hasattr(e.iter, 'isfieldset') and
                   dka.hasnodetype(e.target, dha.PatTuple) and
                   len(e.target.elts) == 2 and
                   dka.hasnodetype(e.target.elts[0], dha.PatVar))
        isfieldfirst = e.target.elts[0].id if isfield else None
        
        if isfieldfirst is not None and isfieldfirst in boundsyms:
            unboundsyms = set()
        
        enum_list.append((e, targetsyms, unboundsyms, isfieldfirst))
    
    if cond:
        condhandled = False
        condsyms = set(st.gatherSymbols(cond)) & alltargetsyms
    
#    print('---')
#    for e, t, u in enum_list:
#        print(dha.genSyntax(e) + ': ' + ', '.join(s.name for s in t) +
#              ' (' + ', '.join(s.name for s in u) + ') ' + str(len(u)))
#    if cond:
#        print('condsyms: ' + ', '.join(s.name for s in condsyms))
#    print('---')
    
    sorted_clauses = []
    
    # Trying to add...
    # Hack heuristic: prefer orders that, when given the choice,
    # go up using the most recently added clause (depth first).
    
    def clauseorder(elem):
        return len(elem[2])
    
    while len(enum_list) > 0:
        if cond and not condhandled and len(condsyms) == 0:
            sorted_clauses.append((COND, cond))
            condhandled = True
        
        else:
            
            copyel = list(enumerate(enum_list))
            copyel.sort(key = lambda elem: clauseorder(elem[1]))
#            enum_list.sort(key = clauseorder)
            
#            e, ts, us, isff = enum_list[0]
            e, ts, us, isff = copyel[0][1]
            sorted_clauses.append((ENUM, e))
            
            for i, (e2, ts2, us2, isff2) in copyel[1:]:
                us2.difference_update(ts)
                if isff2 is not None and isff2 in ts:
                    us2.clear()
                if cond and not condhandled:
                    condsyms.difference_update(ts)
            
            enum_list.pop(copyel[0][0])
    if cond and not condhandled:
        sorted_clauses.append((COND, cond))
        condhandled = True
    
#    print('---')
#    for k, e in sorted_clauses:
#        print(k + ': ' + dha.genSyntax(e))
#    print('---')
    
    code = body
    for k, cl in reversed(sorted_clauses):
        if k is COND:
            code = [dha.If([dha.CondCase(cl, dha.Block(code))])]
        elif k is ENUM:
            code = enumToClause(cl, dha.Block(code))
        else: assert()
    return code