1.1 --- a/micropython/trans.py Sat Feb 26 01:12:25 2011 +0100
1.2 +++ b/micropython/trans.py Sun Feb 27 02:45:38 2011 +0100
1.3 @@ -49,7 +49,7 @@
1.4
1.5 "Make an exception of the given 'name' using 'node'."
1.6
1.7 - # NOTE: Reserving an attribute plus __class__.
1.8 + # NOTE: Reserving an attribute.
1.9
1.10 self.make_instance(self.get_builtin_class(name, node), 1)
1.11
1.12 @@ -415,13 +415,24 @@
1.13 # Where the last operation (defining the attribute owner) yields a
1.14 # constant...
1.15
1.16 - target_name = self.optimiser.optimise_constant_accessor()
1.17 + target_plus_name = self.optimiser.optimise_constant_accessor()
1.18
1.19 # Only try and discover the position if the target can be resolved.
1.20 # Since instances cannot be constants, this involves classes and
1.21 # modules.
1.22 + # It is acceptable to replace the instruction providing the constant
1.23 + # input because doing so does not lose any input information required by
1.24 + # the replacement instructions.
1.25
1.26 - if target_name is not None:
1.27 + if target_plus_name is not None:
1.28 + target, target_name = target_plus_name
1.29 +
1.30 + # Check for class.__class__.
1.31 +
1.32 + if attrname == "__class__":
1.33 + if isinstance(target, Class):
1.34 + self.replace_active_value(LoadAddress(self.get_builtin("type", node)))
1.35 + return
1.36
1.37 # Access the object table to get the attribute.
1.38
1.39 @@ -432,10 +443,8 @@
1.40
1.41 # Produce a suitable instruction.
1.42
1.43 - if attr.is_static_attribute() and AddressInstruction is not None:
1.44 + if AddressInstruction is not None:
1.45 self.replace_active_value(AddressInstruction(attr))
1.46 - elif not attr.is_static_attribute() and AttrInstruction is not None:
1.47 - self.replace_active_value(AttrInstruction(attr))
1.48 else:
1.49 raise TranslateError("Storing of class or module attribute %r via an object is not permitted." % attrname)
1.50
1.51 @@ -517,7 +526,14 @@
1.52 target_names = self.possible_accessor_types(node)
1.53
1.54 if target_names is not None and len(target_names) == 1:
1.55 - target_name = list(target_names)[0]
1.56 + target_name, is_static = list(target_names)[0]
1.57 +
1.58 + # Check for class.__class__.
1.59 +
1.60 + if attrname == "__class__":
1.61 + if is_static:
1.62 + self.load_builtin("type", node)
1.63 + return
1.64
1.65 # Access the object table to get the attribute.
1.66
1.67 @@ -541,6 +557,27 @@
1.68
1.69 return
1.70
1.71 + # Check for class.__class__.
1.72 +
1.73 + if attrname == "__class__":
1.74 +
1.75 + # Remember the accessor.
1.76 +
1.77 + temp_accessor = self.optimiser.optimise_temp_storage()
1.78 +
1.79 + attr_block = self.new_block()
1.80 + end_block = self.new_block()
1.81 +
1.82 + self.new_op(CheckClass())
1.83 + self.new_op(JumpIfFalse(attr_block))
1.84 + self.load_builtin("type", node)
1.85 + self.new_op(Jump(end_block))
1.86 + self.set_block(attr_block)
1.87 +
1.88 + # Recall the accessor.
1.89 +
1.90 + self.new_op(temp_accessor)
1.91 +
1.92 # Otherwise, perform a normal operation.
1.93
1.94 try:
1.95 @@ -564,6 +601,11 @@
1.96 else:
1.97 self.new_op(AttrIndexInstruction(index))
1.98
1.99 + # Where __class__ was involved, define the start of the following code.
1.100 +
1.101 + if attrname == "__class__":
1.102 + self.set_block(end_block)
1.103 +
1.104 # Invocations involve the following:
1.105 #
1.106 # 1. Reservation of a frame for the arguments
1.107 @@ -1385,14 +1427,14 @@
1.108
1.109 "Make a tuple using the given program 'node'."
1.110
1.111 - # Reserve space for __class__ plus the elements themselves.
1.112 + # Reserve space for the elements themselves.
1.113
1.114 - self.make_instance(self.get_builtin_class("tuple", node), len(node.nodes) + 1)
1.115 + self.make_instance(self.get_builtin_class("tuple", node), len(node.nodes))
1.116 temp = self.get_temp()
1.117
1.118 - # Store using 1-based index values, since __class__ should be at position 0.
1.119 + # Store using 0-based index values.
1.120
1.121 - self._populateSequence(temp, node, 1)
1.122 + self._populateSequence(temp, node)
1.123
1.124 self.new_op(temp)
1.125 self.discard_temp(temp)
1.126 @@ -1409,12 +1451,12 @@
1.127 self.new_op(temp)
1.128 self.record_value()
1.129
1.130 - # Reserve space for __class__ plus _elements (the fragment reference).
1.131 + # Reserve space for _elements (the fragment reference).
1.132
1.133 - self.make_instance(self.get_builtin_class("list", node), 2)
1.134 + self.make_instance(self.get_builtin_class("list", node), 1)
1.135 list_temp = self.get_temp()
1.136 self.new_op(list_temp)
1.137 - self.new_op(StoreAttr(Attr(1, None, None)))
1.138 + self.new_op(StoreAttr(Attr(0, None, None))) # _elements is at position 0
1.139 self.set_source()
1.140 self.discard_value()
1.141