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