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
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)
def visit_AttrEnum(self, node): self.fieldenums = [] self.generic_visit(node) dka.assertnodetype(node.iter, dha.SelName) et = dha.AttrEnum if dha.isPosEnum(node) else dha.NegAttrEnum e = et(node.target, dha.SelName(node.iter.id)) newenums = self.fieldenums_helper() return newenums + [e]
def visit_AttrEnum(self, node): dka.assertnodetype(node.iter, dha.SelName) ssym = node.iter.id et = dha.Enum if dha.isPosEnum(node) else dha.NegEnum if (isinstance(ssym, MSymbol) or dha.isfixset(ssym)): return et(node.target, ssym) iter = dha.genBoundVar(ssym) target = self.visit(node.target) return et(dha.PatTuple([iter, target]), self.getMemSym(target._t))