Exemple #1
0
 def visit_stmt(self, node, *args, **kargs):
     # Save the previous code callback.
     self.push()
     
     # Handle this node.
     result = self.dispatch(node, transform_bypass = True, *args, **kargs)
     if result is None and self.transform_ignorenone:
         result = [node]
     else:
         result = dka.listifyValue(result)
     
     # Handle loop nodes. 
     if dka.hasnodetype(node, {For, While, PatWhile}):
         # Loop nodes can't be replaced by multiple statements,
         # since that would screw up our code insertion.
         assert(len(result) == 1)
         r = result[0]
         
         entrycode = self.code_callback(self.CCB_LOOP_ENTRY)
         # For pattern matches aren't allowed to change during the loop,
         # so we need only insert code to execute upon entering the loop.
         if not dka.hasnodetype(node, For):
             repeatcode = self.code_callback(self.CCB_LOOP_REPEAT)
             r.body.stmtlist.extend(repeatcode)
         newcode = entrycode + result
     
     # Handle normal nodes.
     else:
         precode = self.code_callback(self.CCB_NORMAL)
         newcode = precode + result
     
     # Restore the previous code callback.
     self.pop()
     
     return newcode
Exemple #2
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
Exemple #3
0
def isPatCase(node):
    """Test If case type."""
    if dka.hasnodetype(node, PatCase):
        return True
    elif dka.hasnodetype(node, CondCase):
        return False
    else: assert()
Exemple #4
0
def isAttrEnum(node):
    """Again, this is an implementation detail, testing whether we
    are dealing with AttrEnums or regular Enums."""
    if dka.hasnodetype(node, {Enum, NegEnum}):
        return False
    elif dka.hasnodetype(node, {AttrEnum, NegAttrEnum}):
        return True
    else: assert()
Exemple #5
0
 def visit_RefUpdate(self, node, ind):
     # Should enforce this check someplace else.
     assert(dka.hasnodetype(node.op, {UpAdd, UpRemove}))
     return ('{}{} ref{} {}\n'.format(
             '\t' * ind,
             self.sym_text(node, node.target),
             '++' if dka.hasnodetype(node.op, UpAdd) else '--',
             self.visit(node.value, ind)))
Exemple #6
0
def isAddUpdate(node):
    """Test update type."""
    dka.assertnodetype(node, SetUpdate) 
    if dka.hasnodetype(node.op, UpAdd):
        return True
    elif dka.hasnodetype(node.op, UpRemove):
        return False
    else: assert()
Exemple #7
0
def isBoundPat(node):
    if dka.hasnodetype(node, PatVar):
        return isBoundPatVar(node)
    elif dka.hasnodetype(node, PatTuple):
        return all(isBoundPat(elt) for elt in node.elts)
    elif dka.hasnodetype(node, PatExpr):
        return True
    else:
        assert()
Exemple #8
0
def isPatMatchName(node):
    """Test PatMatch type. This is really an implementation detail,
    to allow the same bit of code to work across different stages
    of the transformation."""
    if dka.hasnodetype(node, PatMatchName):
        return True
    elif dka.hasnodetype(node, PatMatch):
        return False
    else: assert()
Exemple #9
0
def hasWildcards(pattern):
    """Return whether a pattern contains any wildcards."""
    dka.assertnodetype(pattern, dha.pattern)
    if dka.hasnodetype(pattern, dha.PatIgnore):
        return True
    elif dka.hasnodetype(pattern, dha.PatTuple):
        return any(hasWildcards(e) for e in pattern.elts)
    else:
        return False
Exemple #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)
Exemple #11
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
Exemple #12
0
 def visit_BinOp(self, node):
     if dka.hasnodetype(node.op,
             {dha.Add, dha.Sub, dha.Mult, dha.Div, dha.Mod}):
         return ast.BinOp(self.visit(node.left),
                          self.visit(node.op),
                          self.visit(node.right))
     elif dka.hasnodetype(node.op,
             {dha.Eq, dha.NotEq, dha.Lt, dha.LtE, dha.Gt, dha.GtE,
              dha.In, dha.NotIn}):
         return ast.Compare(self.visit(node.left),
                            [self.visit(node.op)],
                            [self.visit(node.right)])
     else: assert()
Exemple #13
0
def tuplematcher(left, right, bindings):
    if (dka.hasnodetype(left, dha.PatTuple) and
        dka.hasnodetype(right, dha.Tuple) and
        len(left.elts) == len(right.elts)):
        return all(tuplematcher(a, b, bindings)
                   for a, b in zip(left.elts, right.elts))
    elif dka.hasnodetype(left, dha.PatVar):
        if dka.hasnodetype(right, dha.Name):
            bindings[left.id] = right.id
            return True
        else:
            return False
    else:
        return False
Exemple #14
0
 def visit_UnaryOp(self, node):
     if dka.hasnodetype(node.op, dha.NotEmpty):
         return ast.Call(ast.Name('bool', ast.Load()),
                         [self.visit(node.operand)],
                         [], None, None)
     
     elif dka.hasnodetype(node.op, dha.Any):
         return ast.Call(ast.Attribute(self.visit(node.operand),
                                       'any', ast.Load()),
                         [], [], None, None)
     
     else:
         return ast.UnaryOp(self.visit(node.op),
                            self.visit(node.operand))
Exemple #15
0
 def visit_SetUpdate(self, node):
     dka.assertnodetype(node.op, {dha.UpAdd, dha.UpRemove})
     op = 'add' if dka.hasnodetype(node.op, dha.UpAdd) \
                else 'remove'
     return ast.Call(ast.Attribute(ast.Name(node.target.name, ast.Load()),
                                   op, ast.Load()),
                     [self.visit(node.value)],
                     [], None, None)
Exemple #16
0
 def visit_RefUpdate(self, node):
     dka.assertnodetype(node.op, {dha.UpAdd, dha.UpRemove})
     func = 'incref' if dka.hasnodetype(node.op, dha.UpAdd) \
                     else 'decref'
     return ast.Call(ast.Attribute(ast.Name(node.target.name, ast.Load()),
                                   func, ast.Load()),
                     [self.visit(node.value)],
                     [], None, None)
Exemple #17
0
 def patmatch_helper(self, patmatch):
     target = self.visit(patmatch.target)
     
     if dka.hasnodetype(patmatch, dha.PatMatch):
         iter = patmatch.iter
     
     elif dka.hasnodetype(patmatch, dha.PatMatchName):
         iter = dha.Name(patmatch.id)
     
     elif dka.hasnodetype(patmatch, dha.PatMatchLookup):
         iter = dha.Lookup(patmatch.id, patmatch.key)
     
     else: assert()
     
     iter = self.visit(iter)
     
     return target, iter
Exemple #18
0
 def visit_UnaryOp(self, node):
     self.generic_visit(node)
     
     op = node.op
     operand = node.operand
     
     if dka.hasnodetype(op, dha.NotEmpty):
         if dka.hasnodetype(operand, dha.Lookup):
             if isforwardmember(operand.id):
                 return dha.UnaryOp(dha.NotEmpty(), operand.key)
     
     elif dka.hasnodetype(op, dha.Any):
         if dka.hasnodetype(operand, dha.Lookup):
             if isforwardmember(operand.id):
                 return dha.UnaryOp(dha.Any(), operand.key)
     
     return node
Exemple #19
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 isfield(ssym):
                 return node
             
             if ismember(ssym):
                 cont, val = matchpair(node.left)
                 return dha.BinOp(val, op, cont)
     
     return node
Exemple #20
0
 def sym_text(self, node, sym):
     # Determine symbol type.
     typestr, kind = (('V', KIND_VSYM) if isinstance(sym, dha.VSymbol) else
                      ('F', KIND_FSYM) if isinstance(sym, dha.FSymbol) else
                      ('X', None))
     
     # Get symbol name and address string.
     symname = str(sym)
     symaddr = hex(id(sym))
     
     # Find the defining scope for the symbol.
     defscope = None
     ctxtscope = getNodeScope(node)
     if ctxtscope is not None and kind is not None:
         val = ctxtscope.lookupSymbolAndScope(sym.name, kind)
         if val is not None:
             defscope, sym = val
     defscopeid = hex(id(defscope)) if defscope is not None else 'None'
     
     # If the symbol is a function, *and* it has a proper Scope child
     # (as opposed to a Symtab child), include its id as well.
     if dka.hasnodetype(node, dha.FunctionDef):
         if nodeHasScope(node):
             ownscopeid = '__' + hex(id(getNodeScope(node)))
         else:
             ownscopeid = '__None'
     else:
         ownscopeid = ''
     
     # If this is an enumvar, and we know whether it is bound or unbound, say which it is.
     if dka.hasnodetype(node, dha.PatVar):
         boundedness = ('?' if node.bnd is dha.P_UNKNOWN else
                        '=' if node.bnd is dha.P_BOUND else
                        '*' if node.bnd is dha.P_UNBOUND else
                        '!?!')
     else:
         boundedness = ''
     
     return ((boundedness if self.show_boundedness else '')
           + symname
           + (('_' + typestr) if self.show_typestr else '')
           + (('_' + symaddr) if self.show_symaddr else '')
           + (('$' + defscopeid) if self.show_defscopeid else '')
           + (ownscopeid if self.show_ownscopeid else ''))
Exemple #21
0
 def visit_SetUpdate(self, node):
     op = node.op
     mod = op.mod
     
     # No change to addition and removal updates.
     if dka.hasnodetype(op, {dha.UpAdd, dha.UpRemove}):
         return
     
     elif dka.hasnodetype(op, {dha.UpUnion, dha.UpDiff}):
         isunion = dka.hasnodetype(op, dha.UpUnion)
         return genUnionDiffCode(node.target, node.value.id, isunion, mod)
     
     elif dka.hasnodetype(op, dha.UpClear):
         return genClearCode(node.target, mod)
     
     elif dka.hasnodetype(op, dha.UpCopy):
         return genCopyCode(node.target, node.value.id, mod)
     
     else: assert()
Exemple #22
0
 def visit_UnaryOp(self, node):
     self.generic_visit(node)
     
     op = node.op
     operand = node.operand
     
     if dka.hasnodetype(op, dha.NotEmpty):
         if dka.hasnodetype(operand, dha.Lookup):
             if isforwardfield(operand.id):
                 attr = operand.id.host.attr
                 has = dha.HasAttr(operand.key, attr)
                 return has
     
     elif dka.hasnodetype(op, dha.Any):
         if dka.hasnodetype(operand, dha.Lookup):
             if isforwardfield(operand.id):
                 attr = operand.id.host.attr
                 return dha.Attribute(operand.key, attr)
     
     return node
Exemple #23
0
 def enums_helper(self, enums):
     generators = []
     
     for enum in enums:
         
         if dka.hasnodetype(enum, dha.EnumFor):
             target = self.visit(enum.target)
             iter = self.visit(enum.iter)
             generators.append(ast.comprehension(target, iter, []))
         
         elif dka.hasnodetype(enum, dha.EnumIf):
             assert(len(generators) > 0)
             target = self.visit(enum.target)
             iter = self.visit(enum.iter)
             generators[-1].ifs.append(
                 ast.Compare(target, [ast.In()], [iter]))
         
         else: assert()
     
     return generators
Exemple #24
0
 def visit_SetUpdate(self, node, ind):
     if not dka.hasnodetype(node.op, UpClear):
         return ('{}{} {} {}\n'.format(
                 '\t' * ind,
                 self.sym_text(node, node.target),
                 self.visit(node.op, ind),
                 self.visit(node.value, ind)))
     else:
         return ('{}{} {}\n'.format(
                 '\t' * ind,
                 self.visit(node.op, ind),
                 self.sym_text(node, node.target)))
Exemple #25
0
 def visit_PatMatch(self, node):
     self.generic_visit(node)
     
     if (dka.hasnodetype(node.iter, dha.Name) and
         dha.isfixset(node.iter.id)):
         elem = self.visit(node.target)
         return dha.PatMatchName(elem, node.iter.id)
     
     cont = dha.valueToPattern(node.iter, dha.P_BOUND)
     elem = self.visit(node.target)
     return dha.PatMatchName(dha.PatTuple([cont, elem]),
                             self.getMemSym(elem._t))
Exemple #26
0
 def visit_If(self, node, ind):
     result = ''
     
     def el(c):
         return '' if c is node.cases[0] else 'el'
     
     for c in node.cases:
         
         if dka.hasnodetype(c, CondCase):
             result += ('{}{}if {}:\n{}'.format(
                        '\t' * ind,
                        el(c),
                        self.visit(c.cond, ind),
                        self.visit(c.body, ind)))
         
         elif dka.hasnodetype(c, PatCase):
             result += ('{}{}if {}:\n{}'.format(
                        '\t' * ind,
                        el(c),
                        self.visit(c.match, ind),
                        self.visit(c.body, ind)))
         
         elif dka.hasnodetype(c, ApplCase):
             result += ('{}{}if {} appliesto {}:\n{}'.format(
                         '\t' * ind,
                         el(c),
                         self.visit(c.target, ind),
                         self.visit(c.value, ind),
                         self.visit(c.body, ind)))
         
         else: assert()
     
     if node.orelse:
         result += ('{}else:\n{}'.format(
                    '\t' * ind,
                    self.visit(node.orelse, ind)))
     
     return result
Exemple #27
0
 def visit_Compare(self, node):
     # Make sure only simple comparisons are used.
     if len(node.comparators) > 1:
         raise PythonToDARhiError('Complex comparison used')
     
     # Turn In, Not In into Match nodes.
     op = self.visit(node.ops[0])
     if dka.hasnodetype(op, {dha.In, dha.NotIn}):
         target = self.pattern_helper(node.left)
         iter = self.visit(node.comparators[0])
         if self.objectdomain:
             code = dha.Match(dha.PatMatch(target, iter), dka.Symtab())
         else:
             dka.assertnodetype(iter, dha.Name)
             code = dha.Match(dha.PatMatchName(target, iter.id), dka.Symtab())
         if dka.hasnodetype(op, {dha.NotIn}):
             code = dha.UnaryOp(dha.Not(), code)
         return code
     
     else:
         left = self.visit(node.left)
         right = self.visit(node.comparators[0])
         return dha.BinOp(left, op, right)
Exemple #28
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
Exemple #29
0
 def visit_Expr(self, node):
     # An "is" expression is an invariant definition.
     if isinstance(node.value, ast.Compare):
         cm = node.value
         if (isinstance(cm.left, ast.Name) and
             len(cm.ops) == 1 and
             isinstance(cm.ops[0], ast.Is)):
             sym = genCompSym(cm.left.id)
             value = self.visit(cm.comparators[0])
             if not dka.hasnodetype(value, dha.RelSetComp):
                 raise PythonToDARhiError('Invalid invariant definition')
             return dha.InvDef(sym, value)
         else:
             raise PythonToDARhiError('Standalone expression statement')
     
     # Otherwise, an expression node should be a call to a procedure.
     
     # Check that it's a call.
     if not isinstance(node.value, ast.Call):
         raise PythonToDARhiError('Standalone expression statement')
     call = node.value
     
     # Special attributed calls are used to express set updates.
     if isinstance(call.func, ast.Attribute):
         updatemap = {'add':     dha.UpAdd,
                      'remove':  dha.UpRemove,
                      'union':   dha.UpUnion,
                      'diff':    dha.UpDiff,
                      'clear':   dha.UpClear,
                      'copy':    dha.UpCopy}
         isclear = call.func.attr == 'clear'
         if (isinstance(call.func.value, ast.Name) and
             call.func.attr in updatemap):
             if len(call.args) != (0 if isclear else 1):
                 raise PythonToDARhiError('Invalid number of arguments to set update')
             mod = dha.UP_STRICT if self.strict else dha.UP_NONSTRICT
             return dha.SetUpdate(genVSym(call.func.value.id),
                                  updatemap[call.func.attr](mod),
                                  self.visit(call.args[0]) if not isclear else dha.Num(0))
     
     return self.call_helper(call, isstmt=True)
Exemple #30
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)