Lichen

Changeset

508:6d062b05c250
2017-01-24 Paul Boddie raw files shortlog changelog graph Removed optimised sequence assignment involving equal length sequences because it will not work in general. It could, however, be reintroduced in cases where local or global names are involved and can be shown not to conflict with each other. Made the generator-like test use a swap operation and added a dedicated swap test.
common.py (file) tests/fib.py (file) tests/swap.py (file)
     1.1 --- a/common.py	Tue Jan 24 17:20:35 2017 +0100
     1.2 +++ b/common.py	Tue Jan 24 19:10:31 2017 +0100
     1.3 @@ -4,7 +4,7 @@
     1.4  Common functions.
     1.5  
     1.6  Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013,
     1.7 -              2014, 2015, 2016 Paul Boddie <paul@boddie.org.uk>
     1.8 +              2014, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
     1.9  
    1.10  This program is free software; you can redistribute it and/or modify it under
    1.11  the terms of the GNU General Public License as published by the Free Software
    1.12 @@ -394,16 +394,9 @@
    1.13  
    1.14          name_ref = self.process_structure_node(expr)
    1.15  
    1.16 -        # Either unpack the items and present them directly to each assignment
    1.17 -        # node.
    1.18 +        # Have the assignment nodes access each item via the sequence API.
    1.19  
    1.20 -        if isinstance(name_ref, LiteralSequenceRef):
    1.21 -            self.process_literal_sequence_items(n, name_ref)
    1.22 -
    1.23 -        # Or have the assignment nodes access each item via the sequence API.
    1.24 -
    1.25 -        else:
    1.26 -            self.process_assignment_node_items_by_position(n, expr, name_ref)
    1.27 +        self.process_assignment_node_items_by_position(n, expr, name_ref)
    1.28  
    1.29      def process_assignment_node_items_by_position(self, n, expr, name_ref):
    1.30  
    1.31 @@ -417,8 +410,14 @@
    1.32  
    1.33          assignments = []
    1.34  
    1.35 -        if isinstance(name_ref, NameRef):
    1.36 +        # Employ existing names to access the sequence.
    1.37 +        # Literal sequences do not provide names of accessible objects.
    1.38 +
    1.39 +        if isinstance(name_ref, NameRef) and not isinstance(name_ref, LiteralSequenceRef):
    1.40              temp = name_ref.name
    1.41 +
    1.42 +        # For other expressions, create a temporary name to reference the items.
    1.43 +
    1.44          else:
    1.45              temp = self.get_temporary_name()
    1.46              self.next_temporary()
    1.47 @@ -427,6 +426,8 @@
    1.48                  compiler.ast.Assign([compiler.ast.AssName(temp, "OP_ASSIGN")], expr)
    1.49                  )
    1.50  
    1.51 +        # Assign the items to the target nodes.
    1.52 +
    1.53          for i, node in enumerate(n.nodes):
    1.54              assignments.append(
    1.55                  compiler.ast.Assign([node], compiler.ast.Subscript(
     2.1 --- a/tests/fib.py	Tue Jan 24 17:20:35 2017 +0100
     2.2 +++ b/tests/fib.py	Tue Jan 24 19:10:31 2017 +0100
     2.3 @@ -4,8 +4,7 @@
     2.4  
     2.5      def next(self):
     2.6          result = self.b
     2.7 -        #self.a, self.b = self.b, self.a + self.b
     2.8 -        self.b, self.a = self.a + self.b, result
     2.9 +        self.a, self.b = self.b, self.a + self.b
    2.10          return result
    2.11  
    2.12  seq = fib()
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tests/swap.py	Tue Jan 24 19:10:31 2017 +0100
     3.3 @@ -0,0 +1,10 @@
     3.4 +class C:
     3.5 +    a = 1; b = 2; c = 3
     3.6 +
     3.7 +print C.a, C.b, C.c                     # 1 2 3
     3.8 +C.a, C.b, C.c = C.c, C.b, C.a
     3.9 +print C.a, C.b, C.c                     # 3 2 1
    3.10 +
    3.11 +D = C
    3.12 +C.a, C.b, C.c = D.c, D.b, D.a
    3.13 +print C.a, C.b, C.c                     # 1 2 3