def visit_Call(self, node): if isinstance(node.func, ast.Name): # Catch bool, and interpret it as a set emptyness check. if node.func.id == 'bool': if len(node.args) != 1: raise PythonToDARhiError('Invalid call') iter = self.visit(node.args[0]) if self.objectdomain: return dha.Match(dha.PatMatch(dha.genUnboundVar(st.getFreshNSymbol()), iter), dka.Symtab()) else: dka.assertnodetype(iter, dha.Name) return dha.Match(dha.PatMatchName(dha.genUnboundVar(st.getFreshNSymbol()), iter.id), dka.Symtab()) # Catch hasattr. elif node.func.id == 'hasattr': if len(node.args) != 2: raise PythonToDARhiError('Invalid call') if not isinstance(node.args[1], ast.Str): raise PythonToDARhiError('Reflection not allowed in hasattr') return dha.HasAttr(self.visit(node.args[0]), node.args[1].s) elif isinstance(node.func, ast.Attribute): # Catch any. if node.func.attr == 'any': if len(node.args) != 0: raise PythonToDARhiError('Invalid call') return dha.UnaryOp(dha.Any(), self.visit(node.func.value)) return self.call_helper(node, isstmt=False)
def visit_PatVar(self, node): v = st.getFreshNSymbol() if dha.isBoundPatVar(node): self.bounds.append(dha.Name(v)) return dha.genUnboundVar(v) else: self.unbounds.append(dha.Name(v)) return dha.genUnboundVar(v)
def genUnionDiffCode(leftsym, rightsym, isunion, mod): v = st.getFreshNSymbol() simpleop = dha.UpAdd(mod) if isunion else dha.UpRemove(mod) update = [dha.SetUpdate(leftsym, simpleop, dha.Name(v))] code = [dha.For(dha.PatMatchName(dha.genUnboundVar(v), rightsym), dha.Block(update))] return code
def genClearCode(setsym, mod): """Generate code to empty a set.""" v = st.getFreshNSymbol() match = dha.PatMatchName(dha.genUnboundVar(v), setsym) update = [dha.SetUpdate(setsym, dha.UpRemove(mod), dha.Name(v))] code = [dha.PatWhile(match, dha.Block(update))] return code
def visit_Assign(self, node): if len(node.targets) != 1: raise PythonToDARhiError('Invalid assignment') if isinstance(node.targets[0], ast.Name): sym = genVSym(node.targets[0].id) # Handle variable reinitialization to a new object. if (isinstance(node.value, ast.Name) and node.value.id == 'new'): return dha.Reinit(sym) # if isinstance(node.value, ast.Attribute): # if not isinstance(node.value.value, ast.Name): # raise PythonToDARhiError('Invalid assignment') # source = genVSym(node.value.value.id) # return dha.AttrRetrieval(sym, source, # node.value.attr) # else: # return dha.Assign(dha.PatVar(sym, dha.P_UNBOUND), # self.visit(node.value)) return dha.Assign(dha.genUnboundVar(sym), self.visit(node.value)) elif isinstance(node.targets[0], ast.Attribute): sym = genVSym(node.targets[0].value.id) return dha.AttrUpdate(sym, node.targets[0].attr, self.visit(node.value)) else: raise PythonToDARhiError('Invalid assignment')
def visit_PatVar(self, node): if dha.isBoundPatVar(node): self.bounds.append(dha.Name(node.id)) return "b" else: self.unbounds.append(dha.genUnboundVar(node.id)) return "u"
def fieldenums_helper(self): """Generate actual enumerators for the fieldenums list, then clear the fieldenums list.""" newenums = [dha.AttrEnum(dha.PatTuple([dha.genBoundVar(id), dha.genUnboundVar(v)]), dha.SelName(self.getFieldSym(attr, t))) for (id, attr), v, t in self.fieldenums] self.fieldenums = [] return newenums
def visit_Pick2nd(self, node): self.generic_visit(node) tup = dha.PatTuple([dha.PatExpr(node.key), dha.genUnboundVar(st.getFreshNSymbol())]) mask, bounds, unbounds = getPatInfo(tup) ssym = node.id auxsym = self.getAuxSym(ssym, mask, tup) code = dha.UnaryOp(dha.Any(), dha.Lookup(auxsym, bounds)) return code
def visit_PatIgnore(self, node): return dha.genUnboundVar(st.getFreshNSymbol())
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
def visit_PatExpr(self, node): v = st.getFreshNSymbol() self.bounds.append(dha.Name(v)) return dha.genUnboundVar(v)
def visit_HasAttr(self, node): self.generic_visit(node) fs = self.getFieldSym(node.attr, node.value._t) tup = dha.PatTuple([dha.PatExpr(node.value), dha.genUnboundVar(st.getFreshNSymbol())]) return dha.Match(dha.PatMatchName(tup, fs), dka.Symtab())
def visit_PatIgnore(self, node): return dha.genUnboundVar(dummysym)
def visit_PatExpr(self, node): return dha.genUnboundVar(dummysym)