1.1 --- a/micropython/ast.py Sun Sep 28 21:54:03 2008 +0200
1.2 +++ b/micropython/ast.py Sun Sep 28 23:14:54 2008 +0200
1.3 @@ -303,6 +303,25 @@
1.4 if self.optimiser.optimise_constant_storage():
1.5 self.remove_op()
1.6
1.7 + def is_immediate_user(self, node):
1.8 +
1.9 + """
1.10 + Return whether 'node' is an immediate user of an assignment expression.
1.11 + """
1.12 +
1.13 + return isinstance(node, (compiler.ast.AssName, compiler.ast.AssAttr))
1.14 +
1.15 + def has_immediate_usage(self, nodes):
1.16 +
1.17 + """
1.18 + Return whether 'nodes' are all immediate users of an assignment expression.
1.19 + """
1.20 +
1.21 + for n in nodes:
1.22 + if not self.is_immediate_user(n):
1.23 + return 0
1.24 + return 1
1.25 +
1.26 # Temporary storage administration.
1.27
1.28 def get_temp(self):
1.29 @@ -317,6 +336,13 @@
1.30 return LoadTemp(position_in_frame)
1.31
1.32 def reserve_temp(self, temp_position=None):
1.33 +
1.34 + """
1.35 + Reserve a new temporary storage position, or if the optional
1.36 + 'temp_position' is specified, ensure that this particular position is
1.37 + reserved.
1.38 + """
1.39 +
1.40 if temp_position is not None:
1.41 pass
1.42 elif not self.temp_positions:
1.43 @@ -328,20 +354,38 @@
1.44 return self.unit.all_local_usage + temp_position # position in frame
1.45
1.46 def ensure_temp(self, instruction=None):
1.47 +
1.48 + """
1.49 + Ensure that the 'instruction' is using a reserved temporary storage
1.50 + position.
1.51 + """
1.52 +
1.53 if isinstance(instruction, LoadTemp):
1.54 temp_position = instruction.attr - self.unit.all_local_usage
1.55 self.reserve_temp(temp_position)
1.56
1.57 def discard_temp(self, instruction=None):
1.58 +
1.59 + "Discard any temporary storage position used by 'instruction'."
1.60 +
1.61 if isinstance(instruction, LoadTemp):
1.62 temp_position = instruction.attr - self.unit.all_local_usage
1.63 self.free_temp(temp_position)
1.64
1.65 def free_temp(self, temp_position):
1.66 +
1.67 + "Free the temporary storage position specified by 'temp_position'."
1.68 +
1.69 if temp_position in self.temp_positions:
1.70 self.temp_positions.remove(temp_position)
1.71
1.72 def set_frame_usage(self, node, extend):
1.73 +
1.74 + """
1.75 + Ensure that the frame usage for the unit associated with 'node' is set
1.76 + on the 'extend' instruction.
1.77 + """
1.78 +
1.79 ntemp = self.max_temp_position + 1
1.80 extend.attr = ntemp + node.unit.local_usage # NOTE: See get_code for similar code.
1.81
1.82 @@ -1237,20 +1281,17 @@
1.83 def visitAssert(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Assert")
1.84
1.85 def visitAssign(self, node):
1.86 +
1.87 + """
1.88 + Evaluate the expression from the given 'node' and assign it to the
1.89 + associated recipients.
1.90 + """
1.91 +
1.92 self.dispatch(node.expr)
1.93
1.94 - # Check nodes for immediate usage.
1.95 -
1.96 - immediate = 1
1.97 -
1.98 - for n in node.nodes:
1.99 - if not isinstance(n, (compiler.ast.AssName, compiler.ast.AssAttr)):
1.100 - immediate = 0
1.101 - break
1.102 -
1.103 # Record the value and then dispatch to the assignment targets.
1.104
1.105 - self.record_value(immediate)
1.106 + self.record_value(self.has_immediate_usage(node.nodes))
1.107
1.108 for n in node.nodes:
1.109 self.dispatch(n)
1.110 @@ -1258,10 +1299,19 @@
1.111 self.discard_value()
1.112
1.113 def visitAssAttr(self, node):
1.114 +
1.115 + "Assign the assignment expression to the recipient 'node'."
1.116 +
1.117 self._visitAttr(node, self.attribute_store_instructions)
1.118 self.set_source()
1.119
1.120 def visitAssList(self, node):
1.121 +
1.122 + """
1.123 + Assign items from the assignment expression to each of the recipients
1.124 + found within the given 'node'.
1.125 + """
1.126 +
1.127 for i, n in enumerate(node.nodes):
1.128 self._startCallFunc()
1.129 self.new_op(self.expr_temp[-1])
1.130 @@ -1271,12 +1321,18 @@
1.131 self._endCallFunc(temp, target)
1.132
1.133 # Provide a different source value.
1.134 -
1.135 - self.record_value(0)
1.136 + # NOTE: Permitting immediate usage given that neither name nor
1.137 + # NOTE: attribute accesses should involve a function call
1.138 + # NOTE: overwriting the above result.
1.139 +
1.140 + self.record_value(self.is_immediate_user(n))
1.141 self.dispatch(n)
1.142 self.discard_value()
1.143
1.144 def visitAssName(self, node):
1.145 +
1.146 + "Assign the assignment expression to the recipient 'node'."
1.147 +
1.148 self._visitName(node, self.name_store_instructions)
1.149 self.set_source()
1.150