simplify

Changeset

6:e7738c10964d
2006-07-11 paulb raw files shortlog changelog graph Added Slice support, along with Slice participation in AugAssign node groups. Added a dispatch_or_none convenience method.
simplified.py (file) simplify.py (file) tests/augassign.py (file) tests/slice.py (file)
     1.1 --- a/simplified.py	Sun Jul 09 14:45:36 2006 +0200
     1.2 +++ b/simplified.py	Tue Jul 11 00:53:56 2006 +0200
     1.3 @@ -43,7 +43,7 @@
     1.4          if hasattr(self, "name"):
     1.5              return "%s '%s' (at %x)" % (self.__class__, self.name, id(self))
     1.6          if hasattr(self, "index"):
     1.7 -            return "%s (%d) (at %x)" % (self.__class__, self.index, id(self))
     1.8 +            return "%s (%s) (at %x)" % (self.__class__, self.index, id(self))
     1.9          elif hasattr(self, "value"):
    1.10              return "%s %s (at %x)" % (self.__class__, repr(self.value), id(self))
    1.11          elif hasattr(self, "ref"):
     2.1 --- a/simplify.py	Sun Jul 09 14:45:36 2006 +0200
     2.2 +++ b/simplify.py	Tue Jul 11 00:53:56 2006 +0200
     2.3 @@ -62,6 +62,12 @@
     2.4              results.append(self.dispatch(node, *args))
     2.5          return results
     2.6  
     2.7 +    def dispatch_or_none(self, node, *args):
     2.8 +        if node is not None:
     2.9 +            return self.dispatch(node, *args)
    2.10 +        else:
    2.11 +            return LoadName(name="None")
    2.12 +
    2.13      # Placeholder or deletion transformations.
    2.14  
    2.15      def visitStmt(self, stmt):
    2.16 @@ -234,23 +240,43 @@
    2.17          # Simple augmented assignment: name += expr
    2.18  
    2.19          if isinstance(augassign.node, compiler.ast.Name):
    2.20 -            node = self.dispatch(augassign.node)
    2.21 +            name = augassign.node
    2.22 +            node = self.dispatch(name)
    2.23              get_incremented = StoreTemp(
    2.24                  expr=Invoke(expr=LoadAttr(expr=node, name=self.augassign_methods[augassign.op]), args=[expr])
    2.25                  )
    2.26 -            store = StoreName(expr=LoadTemp(), name=augassign.node.name)
    2.27 +            store = StoreName(expr=LoadTemp(), name=name.name)
    2.28              result.code = [get_incremented, store, ReleaseTemp()]
    2.29  
    2.30          # Complicated augmented assignment: expr.attr += expr
    2.31  
    2.32          elif isinstance(augassign.node, compiler.ast.Getattr):
    2.33 -            store_expr = StoreTemp(index=1, expr=self.dispatch(augassign.node.expr))
    2.34 -            node_attr = LoadAttr(expr=LoadTemp(index=1), name=augassign.node.attrname)
    2.35 +
    2.36 +            # <expr> -> <expr>.attr.__xxx__(
    2.37 +
    2.38 +            getattr = augassign.node
    2.39 +            store_expr = StoreTemp(index="expr", expr=self.dispatch(getattr.expr))
    2.40 +            node_attr = LoadAttr(expr=LoadTemp(index="expr"), name=getattr.attrname)
    2.41              get_incremented = StoreTemp(
    2.42                  expr=Invoke(expr=LoadAttr(expr=node_attr, name=self.augassign_methods[augassign.op]), args=[expr])
    2.43                  )
    2.44 -            store = StoreAttr(expr=LoadTemp(), lvalue=LoadTemp(index=1), name=augassign.node.attrname)
    2.45 -            result.code = [store_expr, get_incremented, store, ReleaseTemp(index=1), ReleaseTemp()]
    2.46 +            store = StoreAttr(expr=LoadTemp(), lvalue=LoadTemp(index="expr"), name=getattr.attrname)
    2.47 +            result.code = [store_expr, get_incremented, store, ReleaseTemp(index="expr"), ReleaseTemp()]
    2.48 +
    2.49 +        # Complicated augassign using slices and subscripts.
    2.50 +
    2.51 +        elif isinstance(augassign.node, compiler.ast.Slice):
    2.52 +            slice = augassign.node
    2.53 +            store_expr = StoreTemp(index="expr", expr=self.dispatch(slice.expr))
    2.54 +            store_lower = StoreTemp(index="lower", expr=self.dispatch_or_none(slice.lower))
    2.55 +            store_upper = StoreTemp(index="upper", expr=self.dispatch_or_none(slice.upper))
    2.56 +            node_slice = self._visitSlice(LoadTemp(index="expr"), LoadTemp(index="lower"), LoadTemp(index="upper"), "OP_APPLY")
    2.57 +            get_incremented = StoreTemp(
    2.58 +                expr=Invoke(expr=LoadAttr(expr=node_slice, name=self.augassign_methods[augassign.op]), args=[expr])
    2.59 +                )
    2.60 +            store = self._visitSlice(LoadTemp(index="expr"), LoadTemp(index="lower"), LoadTemp(index="upper"), "OP_ASSIGN", expr)
    2.61 +            result.code = [store_expr, store_lower, store_upper, get_incremented, store,
    2.62 +                ReleaseTemp(index="expr"), ReleaseTemp(index="lower"), ReleaseTemp(index="upper"), ReleaseTemp()]
    2.63  
    2.64          else:
    2.65              raise NotImplementedError, augassign.node.__class__
    2.66 @@ -294,6 +320,28 @@
    2.67          result = StoreAttr(assattr, name=assattr.attrname, lvalue=lvalue, expr=expr)
    2.68          return result
    2.69  
    2.70 +    def _visitSlice(self, expr, lower, upper, flags, value=None):
    2.71 +        if flags == "OP_ASSIGN":
    2.72 +            args = [value]
    2.73 +            result = Invoke(expr=LoadAttr(expr=expr, name="__setslice__"))
    2.74 +        elif flags == "OP_APPLY":
    2.75 +            args = []
    2.76 +            result = Invoke(expr=LoadAttr(expr=expr, name="__getslice__"))
    2.77 +        else:
    2.78 +            raise NotImplementedError, flags
    2.79 +
    2.80 +        # Add the dimensions.
    2.81 +
    2.82 +        args.insert(0, lower)
    2.83 +        args.insert(1, upper)
    2.84 +
    2.85 +        result.args = args
    2.86 +        return result
    2.87 +
    2.88 +    def visitSlice(self, slice, in_sequence=0):
    2.89 +        value = self._visitAssNameOrAttr(slice, in_sequence)
    2.90 +        return self._visitSlice(self.dispatch(slice.expr), self.dispatch_or_none(slice.lower), self.dispatch_or_none(slice.upper), slice.flags, value)
    2.91 +
    2.92      # Invocation and subprogram transformations.
    2.93  
    2.94      def _visitFunction(self, function, subprogram):
     3.1 --- a/tests/augassign.py	Sun Jul 09 14:45:36 2006 +0200
     3.2 +++ b/tests/augassign.py	Tue Jul 11 00:53:56 2006 +0200
     3.3 @@ -1,3 +1,5 @@
     3.4  a += b
     3.5  a.b += c
     3.6  a.b().c += d
     3.7 +a[b:c] += d
     3.8 +a.b[c:] += d
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tests/slice.py	Tue Jul 11 00:53:56 2006 +0200
     4.3 @@ -0,0 +1,6 @@
     4.4 +a[x:y]
     4.5 +a[x:]
     4.6 +a[:x]
     4.7 +p[q:r] = s
     4.8 +p[q:] = s
     4.9 +p[:q] = s