# HG changeset patch # User Paul Boddie # Date 1222636494 -7200 # Node ID bde27c59cb8498be571bf9aa9cec97ef2d8d0039 # Parent 98862cdebb1ec166f86edf318c8f7d5c2f0356fa Introduced immediate usage assessment for AssList/AssTuple, along with separate methods to perform the assessment on nodes. Added some docstrings. diff -r 98862cdebb1e -r bde27c59cb84 micropython/ast.py --- a/micropython/ast.py Sun Sep 28 21:54:03 2008 +0200 +++ b/micropython/ast.py Sun Sep 28 23:14:54 2008 +0200 @@ -303,6 +303,25 @@ if self.optimiser.optimise_constant_storage(): self.remove_op() + def is_immediate_user(self, node): + + """ + Return whether 'node' is an immediate user of an assignment expression. + """ + + return isinstance(node, (compiler.ast.AssName, compiler.ast.AssAttr)) + + def has_immediate_usage(self, nodes): + + """ + Return whether 'nodes' are all immediate users of an assignment expression. + """ + + for n in nodes: + if not self.is_immediate_user(n): + return 0 + return 1 + # Temporary storage administration. def get_temp(self): @@ -317,6 +336,13 @@ return LoadTemp(position_in_frame) def reserve_temp(self, temp_position=None): + + """ + Reserve a new temporary storage position, or if the optional + 'temp_position' is specified, ensure that this particular position is + reserved. + """ + if temp_position is not None: pass elif not self.temp_positions: @@ -328,20 +354,38 @@ return self.unit.all_local_usage + temp_position # position in frame def ensure_temp(self, instruction=None): + + """ + Ensure that the 'instruction' is using a reserved temporary storage + position. + """ + if isinstance(instruction, LoadTemp): temp_position = instruction.attr - self.unit.all_local_usage self.reserve_temp(temp_position) def discard_temp(self, instruction=None): + + "Discard any temporary storage position used by 'instruction'." + if isinstance(instruction, LoadTemp): temp_position = instruction.attr - self.unit.all_local_usage self.free_temp(temp_position) def free_temp(self, temp_position): + + "Free the temporary storage position specified by 'temp_position'." + if temp_position in self.temp_positions: self.temp_positions.remove(temp_position) def set_frame_usage(self, node, extend): + + """ + Ensure that the frame usage for the unit associated with 'node' is set + on the 'extend' instruction. + """ + ntemp = self.max_temp_position + 1 extend.attr = ntemp + node.unit.local_usage # NOTE: See get_code for similar code. @@ -1237,20 +1281,17 @@ def visitAssert(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Assert") def visitAssign(self, node): + + """ + Evaluate the expression from the given 'node' and assign it to the + associated recipients. + """ + self.dispatch(node.expr) - # Check nodes for immediate usage. - - immediate = 1 - - for n in node.nodes: - if not isinstance(n, (compiler.ast.AssName, compiler.ast.AssAttr)): - immediate = 0 - break - # Record the value and then dispatch to the assignment targets. - self.record_value(immediate) + self.record_value(self.has_immediate_usage(node.nodes)) for n in node.nodes: self.dispatch(n) @@ -1258,10 +1299,19 @@ self.discard_value() def visitAssAttr(self, node): + + "Assign the assignment expression to the recipient 'node'." + self._visitAttr(node, self.attribute_store_instructions) self.set_source() def visitAssList(self, node): + + """ + Assign items from the assignment expression to each of the recipients + found within the given 'node'. + """ + for i, n in enumerate(node.nodes): self._startCallFunc() self.new_op(self.expr_temp[-1]) @@ -1271,12 +1321,18 @@ self._endCallFunc(temp, target) # Provide a different source value. - - self.record_value(0) + # NOTE: Permitting immediate usage given that neither name nor + # NOTE: attribute accesses should involve a function call + # NOTE: overwriting the above result. + + self.record_value(self.is_immediate_user(n)) self.dispatch(n) self.discard_value() def visitAssName(self, node): + + "Assign the assignment expression to the recipient 'node'." + self._visitName(node, self.name_store_instructions) self.set_source()