Пример #1
0
def enumToClause(enum, body):
    """Generate a For or If clause (with the specified body)
    that corresponds to an enumerator."""
    ### Could use a little refactoring; break off AttrEnum stuff into separate method.
    if dha.isPosEnum(enum):
        if dha.isAttrEnum(enum):
            code = [dha.For(dha.PatMatch(dka.copy(enum.target),
                                         dha.selectorToAttr(enum.iter)),
                            body)]
        else:
            code = [dha.For(dha.PatMatchName(dka.copy(enum.target),
                                             enum.iter),
                            body)]
    else:
        if dha.isAttrEnum(enum):
            code = [dha.If([dha.CondCase(dha.BinOp(dha.patternToValue(enum.target),
                                                   dha.NotIn(),
                                                   dha.selectorToAttr(enum.iter)),
                                         body)])]
        else:
            code = [dha.If([dha.CondCase(dha.BinOp(dha.patternToValue(enum.target),
                                                   dha.NotIn(),
                                                   dha.Name(enum.iter)),
                                         body)])]
    return code
Пример #2
0
 def genDSetBlock(self, enumnum, upvalexpr):
     compnode = self.compnode
     enumvars = self.info.enumvars
     
     enums = dka.copy(compnode.enums)
     conds = dka.copy(compnode.conds)
     st.cleanPatterns(enums)
     
     suffix = '_up' + str(enumnum)
     
     wittarget = dka.copy(enums[enumnum].target)
     upval = dka.copy(upvalexpr)
     upvalassign = dha.Assign(wittarget, upval)
     elt = du.genDTuple([s for s in enumvars])
     
     if len(enums) > 1:
         maintenums = enums[:enumnum] + enums[enumnum+1:]
         maintcomp = dha.RelSetComp(elt, maintenums, conds, dka.Symtab())
         maintupdate = dha.SetUpdate(self.diffsym, dha.UpUnionNS(), maintcomp)
     else:
         maintupdate = dha.SetUpdate(self.diffsym, dha.UpAddNS(), elt)
     
     code = [upvalassign, maintupdate]
     
     repldict = {s: dha.VSymbol(s.name + suffix)
                 for s in enumvars}
     st.replaceSymbols(code, repldict)
     
     return code
Пример #3
0
 def visit_SetUpdate(self, node):
     self.generic_visit(node)
     
     ssym = node.target
     if ismember(ssym):
         cont, val = matchpair(dka.copy(node.value))
         dka.assertnodetype(cont, {dha.Name, dha.PatVar})
         newnode = dha.SetUpdate(cont.id, dka.copy(node.op), val)
         return [newnode, node]
     
     return node
Пример #4
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
Пример #5
0
 def visit_BinOp(self, node):
     self.generic_visit(node)
     
     op = node.op
     
     if dka.hasnodetype(op, {dha.In, dha.NotIn}):
         
         if dka.hasnodetype(node.right, dha.Name):
             ssym = node.right.id
             
             if not isfield(ssym):
                 return node
             attr = ssym.attr
             
             cont, val = matchpair(node.left)
             has = dha.HasAttr(cont, attr)
             matches = dha.BinOp(dha.Attribute(dka.copy(cont), attr),
                                 dha.Eq(),
                                 val)
             cond = dha.BoolOp(dha.And(), [has, matches])
             
             if dka.hasnodetype(op, dha.NotIn):
                 cond = dha.Not(cond)
             
             return cond
     
     return node
Пример #6
0
 def getAuxSym(self, ssym, mask, pat):
     """Retrieve the auxiliary map symbol for the given set symbol and mask."""
     if (ssym, mask) in self.auxmaskmap:
         auxsym = self.auxmaskmap[(ssym, mask)]
         return auxsym
     else:
         auxsym = AuxMapSymbol(ssym, mask, dka.copy(pat))
         self.auxmaskmap[(ssym, mask)] = auxsym
         return auxsym
Пример #7
0
 def visit_SetCompDef(self, node):
     if node.id is not self.comp:
         return
     
     taginfo = self.comp.info.taginfo
     
     code = []
     
     for tc in taginfo.tagcomps:
         newtc = dka.copy(tc)
         code.append(newtc)
         sym = tc.id
         sym.compdefs.add(newtc)
         self.tagcompsyms.append(sym)
     
     code.append(dka.copy(node))
     
     return code
Пример #8
0
 def visit_SetUpdate(self, node):
     isaddup = dha.isAddUpdate(node)
     
     if node.op.mod is not dha.UP_NONSTRICT:
         return
     
     has = dha.Match(dha.PatMatch(dha.valueToPattern(dka.copy(node.value)),
                                  dha.Name(node.target)),
                     dka.Symtab())
     if isaddup:
         test = dha.UnaryOp(dha.Not(), has)
     else:
         test = has
     
     newupdate = dka.copy(node)
     newupdate.op.mod = dha.UP_STRICT
     
     blk = dha.Block([newupdate])
     return dha.If([dha.CondCase(test, blk)])
Пример #9
0
 def visit_If(self, node):
     self.marker = node
     self.generic_visit(node)
     
     if not (len(node.cases) == 1 and
             dka.hasnodetype(node.cases[0], dha.ApplCase)):
         return
     case = node.cases[0]
     
     wipepat = wipePattern(dka.copy(case.target))
     assign = dha.Assign(dka.copy(case.target), dka.copy(case.value))
     
     bodycode = eliminatedecomp(assign, case.body.stmtlist)
     
     check = dha.CompatTuple(wipepat, dka.copy(case.value))
     newcase = dha.CondCase(check, dha.Block(bodycode))
     code = dha.If([newcase], node.orelse)
     
     return code
Пример #10
0
def patmatchToNormal(patmatch):
    target = patmatch.target
    
    if dka.hasnodetype(patmatch, PatMatchName):
        iter = Name(patmatch.id)
    
    elif dka.hasnodetype(patmatch, PatMatchLookup):
        iter = Lookup(patmatch.id, dka.copy(patmatch.key))
    
    else: assert()
    
    return PatMatch(target, iter)
Пример #11
0
 def visit_PatMatchName(self, node):
     self.generic_visit(node)
     
     id = node.iter
     info = id.info
     params = info.enumparams
     
     if len(params) > 0:
         paramtup = du.genDPatTuple([dha.genBoundVar(sym) for sym in params])
         newtarget = dha.PatTuple([paramtup, dka.copy(node.target)])
         node.target = newtarget
     else:
         pass
Пример #12
0
    def patmatch_helper(self, patmatch):
        target = patmatch.target

        if dka.hasnodetype(patmatch, dha.PatMatchName):
            iter = dha.Name(patmatch.id)

        elif dka.hasnodetype(patmatch, dha.PatMatchLookup):
            iter = dha.Lookup(patmatch.id, dka.copy(patmatch.key))

        else:
            assert ()

        return target, iter
Пример #13
0
    def visit_SetUpdate(self, node):
        ssym = node.target

        code = [node]

        for mask, auxsym in sorted(self.maskmap[ssym], key=lambda elem: elem[1].name):
            pat = auxsym.pat
            tupletree, bounds, unbounds = getDecomposition(pat)

            update = [dha.MapUpdate(auxsym, bounds, dka.copy(node.op), unbounds)]
            newcode = [dha.If([dha.ApplCase(tupletree, node.value, dha.Block(update))])]

            code.extend(newcode)

        return code
Пример #14
0
 def visit_RelEnum(self, node):
     self.generic_visit(node)
     
     id = node.iter
     if not id.hasflag(dha.FLAG_INV):
         return
     
     info = id.info
     params = info.enumparams
     
     if len(params) > 0:
         paramtup = du.genDPatTuple([dha.genBoundVar(sym) for sym in params])
         newtarget = dha.PatTuple([paramtup, dka.copy(node.target)])
         node.target = newtarget
     else:
         pass
Пример #15
0
 def visit_SetUpdate(self, node):
     self.generic_visit(node)
     
     ssym = node.target
     if isfield(ssym):
         attr = ssym.attr
         
         cont, val = matchpair(dka.copy(node.value))
         dka.assertnodetype(cont, {dha.Name, dha.PatVar})
         
         if dha.isAddUpdate(node):
             newnode = dha.AttrUpdate(cont.id, attr, val)
         else:
             newnode = dha.DelAttr(cont.id, attr)
         
         return [newnode, node]
     
     return node
Пример #16
0
    def visit_SetUpdate(self, node):
        sym = node.target
        if hasattr(sym, 'needsmulti') and sym.needsmulti:
            self.multisyms.add(sym)
        else:
            return
        
        isaddup = dha.isAddUpdate(node)
        has = dha.Match(dha.PatMatchName(dha.valueToPattern(dka.copy(node.value)),
                                         node.target),
                        dka.Symtab())
        
        if isaddup:
            test1 = dha.UnaryOp(dha.Not(), has)
            inc1 = dha.RefUpdate(node.target, dka.copy(node.op), dka.copy(node.value))
            inc2 = dka.copy(inc1)
            
            body = dha.Block([dka.copy(node),
                              inc1])
            orelse = dha.Block([inc2])
            
            code = dha.If([dha.CondCase(test1, body)], orelse)
        
        else:
            test1 = has
            test2 = dha.BinOp(dha.GetRefCount(node.target, dka.copy(node.value)),
                              dha.Eq(),
                              dha.Num(0))
            body2 = dha.Block([dka.copy(node)])
            remif = dha.If([dha.CondCase(test2, body2)])
            body1 = [dha.RefUpdate(node.target, dka.copy(node.op), dka.copy(node.value)),
                     remif]
#            code = dha.If([dha.CondCase(test1, body1)])
            code = body1
        
        return code
Пример #17
0
    def genHandler(self, setparam, isaddition):
        compnode = self.compnode
        
        code = []
        
        # Compute differential assignment set.
        for i, enum in enumerate(compnode.enums):
            if enum.iter is setparam:
                code.extend(self.genDSetBlock(i))
        
        # Compute change to result set.
        vartup = du.genDPatTuple([s for s in enumvars])
        match = dha.PatMatchName(vartup, self.diffsym)
        resexpr = dka.copy(compnode.elt)
#        update = dha.SetUpdate(self.resmapsym, dha.UpAddNS(), resexpr)
        update = dha.SetUpdate(self.resmapsym, dha.UpAdd(), resexpr)
        loop = dha.For(match, dha.Block([update]))
        
        code.extend([loop])
Пример #18
0
 def visit_InvDef(self, node):
     dka.assertnodetype(node.value, dha.RelSetComp)
     
     self.generic_visit(node)
     
     compnode = node.value
     info = node.id.info
     params = info.enumparams
     repldict = {sym: dha.VSymbol(sym.name + '_local')
                 for sym in params}
     
     if len(params) > 0:
         paramtup = du.genDTuple([dha.Name(sym) for sym in params])
         newelt = dha.Tuple([paramtup, dka.copy(compnode.elt)])
         compnode.elt = newelt
     else:
         pass
     
     st.cleanPatterns(compnode)
     st.replaceSymbols(compnode, repldict)
Пример #19
0
    def visit_PatWhile(self, node):
        # Transform the PatMatch node first.
        self.generic_visit(node)

        target, iter = self.patmatch_helper(node.match)
        mask = getPatMask(target)

        # If fully bound, replace with a condition While.
        if maskAllBound(mask):
            test = dha.BinOp(dha.patternToValue(target), dha.In(), iter)
            code = dha.While(test, node.body, node.orelse)

        # Otherwise, test non-emptiness and bind.
        else:
            elem = dha.UnaryOp(dha.Any(), iter)
            node.body.stmtlist[:0] = [dha.Assign(target, elem)]
            emptytest = dha.UnaryOp(dha.NotEmpty(), dka.copy(iter))
            code = dha.While(emptytest, node.body, node.orelse)

        return code
Пример #20
0
 def visit_For(self, node):
     self.generic_visit(node)
     
     match = node.match
     if dka.hasnodetype(match, dha.PatMatch):
         return
     ssym = match.id
     
     if isfield(ssym):
         attr = ssym.attr
     elif isfieldaux(ssym):
         attr = ssym.host.attr
     else: assert()
     
     if isforwardfield(ssym):
         cont, val = match.key, match.target
         has = dha.HasAttr(cont, attr)
         bind = dha.Assign(val, dha.Attribute(dka.copy(cont), attr))
         newbody = dha.Block([bind] + node.body.stmtlist)
         return dha.If([dha.CondCase(has, newbody)], node.orelse)
     else:
         newmatch = dha.patmatchToNormal(node.match)
         return dha.For(newmatch, node.body, node.orelse)
Пример #21
0
 def addCode(self, code):
     assert(isinstance(code, list))
     incode = dka.copy(code)
     last = self.code_callback(self.CCB_UNKNOWN)
     newcode = last + incode
     self.code_callback = lambda ccb: dka.copy(newcode)
Пример #22
0
 def visit_Name(self, node):
     if node.id in self.symmapping:
         return dka.copy(self.symmapping[node.id])
     else:
         if self.strict:
             assert()
Пример #23
0
 def setCode(self, code):
     assert(isinstance(code, list))
     incode = dka.copy(code)
     self.code_callback = lambda ccb: dka.copy(incode)