micropython

Changeset

139:29103989ca36
2008-09-05 Paul Boddie raw files shortlog changelog graph Added the final Return instruction to generated images. Fixed the For node processing to store assigned values before visiting assignment nodes. Changed source processing to not use temporary storage optimisations, since the conditions for such optimisations are not met in general when processing assignments. Adopted a list to hold sources (assignment expression values), since list and tuple assignment act on a hierarchy of such values. Added elementary support and tests for list assignment.
micropython/__init__.py (file) micropython/ast.py (file) micropython/inspect.py (file) tests/list_assign.py (file) tests/list_assign2.py (file)
     1.1 --- a/micropython/__init__.py	Thu Sep 04 19:44:39 2008 +0200
     1.2 +++ b/micropython/__init__.py	Fri Sep 05 00:04:20 2008 +0200
     1.3 @@ -142,6 +142,8 @@
     1.4              const.location = pos
     1.5              image.append(const)
     1.6  
     1.7 +        last_module = self.modules_ordered[-1]
     1.8 +
     1.9          for module in self.modules_ordered:
    1.10  
    1.11              if not with_builtins and module.name == "__builtins__":
    1.12 @@ -229,10 +231,12 @@
    1.13  
    1.14              # Append the module top-level code to the image.
    1.15  
    1.16 -            code = trans.get_module_code()
    1.17 +            code = trans.get_module_code(final=(module is last_module))
    1.18              image += code
    1.19              pos += len(code)
    1.20  
    1.21 +        # Remember the generated code and the location of the first instruction.
    1.22 +
    1.23          self.code = image
    1.24          self.code_location = self.modules["__main__"].code_location
    1.25          return image
     2.1 --- a/micropython/ast.py	Thu Sep 04 19:44:39 2008 +0200
     2.2 +++ b/micropython/ast.py	Fri Sep 05 00:04:20 2008 +0200
     2.3 @@ -87,7 +87,7 @@
     2.4  
     2.5          # The temporary storage used by the current assignment expression.
     2.6  
     2.7 -        self.expr_temp = None
     2.8 +        self.expr_temp = []
     2.9  
    2.10          # Wiring within the code.
    2.11  
    2.12 @@ -108,9 +108,12 @@
    2.13      def __repr__(self):
    2.14          return "Translation(%r)" % self.module
    2.15  
    2.16 -    def get_module_code(self):
    2.17 -
    2.18 -        "Return the top-level module code."
    2.19 +    def get_module_code(self, final=0):
    2.20 +
    2.21 +        """
    2.22 +        Return the top-level module code including finalising code if 'final' is
    2.23 +        set to a true value.
    2.24 +        """
    2.25  
    2.26          self.unit = self.module
    2.27          self.code = []
    2.28 @@ -120,6 +123,11 @@
    2.29          if self.module.module is not None:
    2.30              self.dispatch(self.module.module)
    2.31  
    2.32 +        # Finish off the translated program if appropriate.
    2.33 +
    2.34 +        if final:
    2.35 +            self.new_op(Return())
    2.36 +
    2.37          self.unit.temp_usage = self.max_temp_position + 1
    2.38          return self.code
    2.39  
    2.40 @@ -268,17 +276,16 @@
    2.41      # Assignment expression values.
    2.42  
    2.43      def record_value(self):
    2.44 -        self.expr_temp = self._optimise_temp_storage()
    2.45 +        self.expr_temp.append(self.get_temp())
    2.46          self.active_source = self.active
    2.47  
    2.48      def discard_value(self):
    2.49 -        self.discard_temp(self.expr_temp)
    2.50 -        self.expr_temp = None
    2.51 +        self.discard_temp(self.expr_temp.pop())
    2.52          self.active_source = None
    2.53  
    2.54      def set_source(self):
    2.55          if self.active is not None:
    2.56 -            self.active.source = self.expr_temp
    2.57 +            self.active.source = self.expr_temp[-1]
    2.58  
    2.59          # Optimise away constant storage if appropriate.
    2.60  
    2.61 @@ -301,7 +308,7 @@
    2.62          if not self.temp_positions:
    2.63              temp_position = 0
    2.64          else:
    2.65 -            temp_position = max(self.temp_positions)
    2.66 +            temp_position = max(self.temp_positions) + 1
    2.67          self.temp_positions.add(temp_position)
    2.68          self.max_temp_position = max(self.max_temp_position, temp_position)
    2.69          return self.unit.all_local_usage + temp_position # position in frame
    2.70 @@ -1509,23 +1516,37 @@
    2.71          self.record_value()
    2.72  
    2.73          for n in node.nodes:
    2.74 -            self.dispatch(n)
    2.75 +            self.dispatch(n, 1)
    2.76  
    2.77          self.discard_value()
    2.78  
    2.79 -    def visitAssAttr(self, node):
    2.80 +    def visitAssAttr(self, node, top_level=0):
    2.81          self._visitAttr(node, self.attribute_store_instructions)
    2.82          self.set_source()
    2.83  
    2.84 -    def visitAssList(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "AssList")
    2.85 -
    2.86 -    def visitAssName(self, node):
    2.87 +    def visitAssList(self, node, top_level=1):
    2.88 +        for i, n in enumerate(node.nodes):
    2.89 +            self._startCallFunc()
    2.90 +            self.new_op(self.expr_temp[-1])
    2.91 +            self._generateAttr(node, "__getitem__", self.attribute_load_instructions)
    2.92 +            temp, target = self._generateCallFunc([compiler.ast.Const(i)], node)
    2.93 +            self._doCallFunc(temp, target)
    2.94 +            self._endCallFunc(temp, target)
    2.95 +
    2.96 +            # Provide a different source value.
    2.97 +
    2.98 +            self.record_value()
    2.99 +            self.dispatch(n, 0)
   2.100 +            self.discard_value()
   2.101 +
   2.102 +    def visitAssName(self, node, top_level=1):
   2.103  
   2.104          # Optimise away intermediate source storage.
   2.105  
   2.106 -        no_source = self._optimise_source_storage()
   2.107 +        if top_level:
   2.108 +            no_source = self._optimise_source_storage()
   2.109          self._visitName(node, self.name_store_instructions)
   2.110 -        if not no_source:
   2.111 +        if not top_level or not no_source:
   2.112              self.set_source()
   2.113  
   2.114      visitAssTuple = visitAssList
   2.115 @@ -1727,6 +1748,10 @@
   2.116          self._doCallFunc(temp, target)
   2.117          self._endCallFunc(temp, target)
   2.118  
   2.119 +        # Record the value to be assigned.
   2.120 +
   2.121 +        self.record_value()
   2.122 +
   2.123          # Test for StopIteration.
   2.124  
   2.125          self.load_builtin("StopIteration", node)
   2.126 @@ -1739,6 +1764,7 @@
   2.127          # Assign to the target.
   2.128  
   2.129          self.dispatch(node.assign)
   2.130 +        self.discard_value()
   2.131  
   2.132          # Process the body with the current next and exit points.
   2.133  
     3.1 --- a/micropython/inspect.py	Thu Sep 04 19:44:39 2008 +0200
     3.2 +++ b/micropython/inspect.py	Fri Sep 05 00:04:20 2008 +0200
     3.3 @@ -329,8 +329,9 @@
     3.4          return None
     3.5  
     3.6      def visitAssList(self, node):
     3.7 -        for n in node.nodes:
     3.8 +        for i, n in enumerate(node.nodes):
     3.9              self.dispatch(n)
    3.10 +            self._make_constant(i) # for __getitem__(i) at run-time
    3.11          return None
    3.12  
    3.13      def visitAssName(self, node):
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tests/list_assign.py	Fri Sep 05 00:04:20 2008 +0200
     4.3 @@ -0,0 +1,6 @@
     4.4 +#!/usr/bin/env python
     4.5 +
     4.6 +[a, b, c] = [1, 2, 3]
     4.7 +[x, y, z] = list((9, 8, 7))
     4.8 +
     4.9 +# vim: tabstop=4 expandtab shiftwidth=4
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tests/list_assign2.py	Fri Sep 05 00:04:20 2008 +0200
     5.3 @@ -0,0 +1,5 @@
     5.4 +#!/usr/bin/env python
     5.5 +
     5.6 +[d, [e, f], g] = [4, [5, 6], 7]
     5.7 +
     5.8 +# vim: tabstop=4 expandtab shiftwidth=4