1.1 --- a/lib/builtins.py Sat Jan 29 21:07:27 2011 +0100
1.2 +++ b/lib/builtins.py Sat Feb 19 23:29:55 2011 +0100
1.3 @@ -460,15 +460,14 @@
1.4
1.5 # NOTE: CPython insists on tuples, but any sequence might be considered
1.6 # NOTE: acceptable.
1.7 - # NOTE: tuple.__class__ is tuple in micropython!
1.8
1.9 - if cls_or_tuple is not tuple and cls_or_tuple.__class__ is tuple:
1.10 + if _isinstance(cls_or_tuple, tuple):
1.11 for cls in cls_or_tuple:
1.12 - if _isinstance(obj, cls):
1.13 + if obj.__class__ is cls or _isinstance(obj, cls):
1.14 return True
1.15 return False
1.16 else:
1.17 - return _isinstance(obj, cls_or_tuple)
1.18 + return obj.__class__ is cls_or_tuple or _isinstance(obj, cls_or_tuple)
1.19
1.20 def issubclass(obj, cls_or_tuple): pass
1.21
1.22 @@ -610,7 +609,6 @@
1.23 # Special implementation functions.
1.24
1.25 def _isinstance(obj, cls): pass
1.26 -
1.27 def _print(dest, *args): pass
1.28 def _printnl(dest, *args): pass
1.29
2.1 --- a/micropython/rsvp.py Sat Jan 29 21:07:27 2011 +0100
2.2 +++ b/micropython/rsvp.py Sat Feb 19 23:29:55 2011 +0100
2.3 @@ -149,19 +149,34 @@
2.4
2.5 def set_location(self, location, with_builtins):
2.6 location = RSVPObject.set_location(self, location, with_builtins)
2.7 - return location + len(self.raw_data())
2.8 +
2.9 + # Include the __class__ attribute in the size.
2.10 +
2.11 + return location + 1 + len(self.raw_data())
2.12
2.13 def as_raw(self, objtable, paramtable, with_builtins):
2.14 item = self.item
2.15 - # NOTE: Need class details!
2.16 + classcode = objtable.as_list().get_code(item.value_type_name())
2.17 + attrcode = objtable.get_index(item.value_type_name())
2.18 return [
2.19 DataObject(
2.20 - objtable.as_list().get_code(item.value_type_name()),
2.21 - objtable.get_index(item.value_type_name()), # is instance
2.22 + classcode,
2.23 + attrcode, # is instance
2.24 None,
2.25 item.value_type_name(),
2.26 - 1 # size
2.27 + 3 # size (header plus __class__ plus data)
2.28 + ),
2.29 +
2.30 + # The __class__ attribute for instances.
2.31 +
2.32 + DataValue(
2.33 + PlaceholderContext,
2.34 + item.location
2.35 )
2.36 +
2.37 + # NOTE: The RSVP library needs changing if more attributes are added
2.38 + # NOTE: here.
2.39 +
2.40 ] + self.raw_data()
2.41
2.42 def raw_data(self):
3.1 --- a/micropython/trans.py Sat Jan 29 21:07:27 2011 +0100
3.2 +++ b/micropython/trans.py Sat Feb 19 23:29:55 2011 +0100
3.3 @@ -1379,9 +1379,15 @@
3.4
3.5 "Make a tuple using the given program 'node'."
3.6
3.7 - self.make_instance(self.get_builtin_class("tuple", node), len(node.nodes))
3.8 + # Reserve space for __class__ plus the elements themselves.
3.9 +
3.10 + self.make_instance(self.get_builtin_class("tuple", node), len(node.nodes) + 1)
3.11 temp = self.get_temp()
3.12 - self._populateSequence(temp, node)
3.13 +
3.14 + # Store using 1-based index values, since __class__ should be at position 0.
3.15 +
3.16 + self._populateSequence(temp, node, 1)
3.17 +
3.18 self.new_op(temp)
3.19 self.discard_temp(temp)
3.20
3.21 @@ -1397,7 +1403,9 @@
3.22 self.new_op(temp)
3.23 self.record_value()
3.24
3.25 - self.make_instance(self.get_builtin_class("list", node), 1)
3.26 + # Reserve space for __class__ plus _elements (the fragment reference).
3.27 +
3.28 + self.make_instance(self.get_builtin_class("list", node), 2)
3.29 list_temp = self.get_temp()
3.30 self.new_op(list_temp)
3.31 self.new_op(StoreAttr(Attr(0, None, None)))
3.32 @@ -1408,7 +1416,7 @@
3.33 self.discard_temp(temp)
3.34 self.discard_temp(list_temp)
3.35
3.36 - def _populateSequence(self, temp, node):
3.37 + def _populateSequence(self, temp, node, offset=0):
3.38
3.39 """
3.40 Populate a sequence using the given 'temp' reference and program 'node'.
3.41 @@ -1418,7 +1426,7 @@
3.42 self.dispatch(n)
3.43 self.record_value()
3.44 self.new_op(temp)
3.45 - self.new_op(StoreAttr(Attr(i, None, None)))
3.46 + self.new_op(StoreAttr(Attr(i + offset, None, None)))
3.47 self.set_source()
3.48 self.discard_value()
3.49
4.1 --- a/rsvp.py Sat Jan 29 21:07:27 2011 +0100
4.2 +++ b/rsvp.py Sat Feb 19 23:29:55 2011 +0100
4.3 @@ -298,7 +298,7 @@
4.4 value = self.load(attr_location)
4.5
4.6 if value is not None:
4.7 - content = self.load(value.ref + 1)
4.8 + content = self.load(value.ref + Library.instance_data_offset)
4.9 print label, expected, content
4.10 success = success and (int(expected) == content)
4.11 else:
5.1 --- a/rsvplib.py Sat Jan 29 21:07:27 2011 +0100
5.2 +++ b/rsvplib.py Sat Feb 19 23:29:55 2011 +0100
5.3 @@ -26,6 +26,11 @@
5.4
5.5 "Native function implementations."
5.6
5.7 + # NOTE: These attributes need changing if the instance layout changes.
5.8 +
5.9 + instance_data_offset = 2
5.10 + instance_size = 3
5.11 +
5.12 def __init__(self, machine, constants):
5.13
5.14 """
5.15 @@ -77,22 +82,20 @@
5.16 if not (self.machine._CheckInstance(left_value.ref, self.int_class) and
5.17 self.machine._CheckInstance(right_value.ref, self.int_class)):
5.18
5.19 - self.machine.exception = self.machine._MakeObject(2, self.type_error_instance)
5.20 + self.machine.exception = self.machine._MakeObject(self.instance_size, self.type_error_instance)
5.21 return self.machine.RaiseException()
5.22
5.23 - # NOTE: Assume single location for data.
5.24 -
5.25 - left_data = left_value.ref + 1
5.26 - right_data = right_value.ref + 1
5.27 + left_data = left_value.ref + self.instance_data_offset
5.28 + right_data = right_value.ref + self.instance_data_offset
5.29
5.30 # Make a new object.
5.31
5.32 - addr = self.machine._MakeObject(2, self.int_instance)
5.33 + addr = self.machine._MakeObject(self.instance_size, self.int_instance)
5.34
5.35 # Store the result.
5.36 # NOTE: The data is considered ready to use.
5.37
5.38 - self.machine.save(addr + 1, op(self.machine.load(left_data), self.machine.load(right_data)))
5.39 + self.machine.save(addr + self.instance_data_offset, op(self.machine.load(left_data), self.machine.load(right_data)))
5.40
5.41 # Return the new object.
5.42 # Introduce object as context for the new object.
5.43 @@ -118,10 +121,8 @@
5.44 self.machine.result = DataValue(notimpl, notimpl)
5.45 return
5.46
5.47 - # NOTE: Assume single location for data.
5.48 -
5.49 - left_data = left_value.ref + 1
5.50 - right_data = right_value.ref + 1
5.51 + left_data = left_value.ref + self.instance_data_offset
5.52 + right_data = right_value.ref + self.instance_data_offset
5.53
5.54 # Test the data.
5.55 # NOTE: The data is considered ready to use.
5.56 @@ -199,12 +200,10 @@
5.57 # Test operand suitability.
5.58
5.59 if not self.machine._CheckInstance(left_value.ref, self.int_class):
5.60 - self.machine.exception = self.machine._MakeObject(2, self.type_error_instance)
5.61 + self.machine.exception = self.machine._MakeObject(self.instance_size, self.type_error_instance)
5.62 return self.machine.RaiseException()
5.63
5.64 - # NOTE: Assume single location for data.
5.65 -
5.66 - left_data = left_value.ref + 1
5.67 + left_data = left_value.ref + self.instance_data_offset
5.68
5.69 # Test the data.
5.70 # NOTE: The data is considered ready to use.
5.71 @@ -224,21 +223,19 @@
5.72 # Test operand suitability.
5.73
5.74 if not self.machine._CheckInstance(left_value.ref, self.int_class):
5.75 - self.machine.exception = self.machine._MakeObject(2, self.type_error_instance)
5.76 + self.machine.exception = self.machine._MakeObject(self.instance_size, self.type_error_instance)
5.77 return self.machine.RaiseException()
5.78
5.79 - # NOTE: Assume single location for data.
5.80 -
5.81 - left_data = left_value.ref + 1
5.82 + left_data = left_value.ref + self.instance_data_offset
5.83
5.84 # Make a new object.
5.85
5.86 - addr = self.machine._MakeObject(2, self.int_instance)
5.87 + addr = self.machine._MakeObject(self.instance_size, self.int_instance)
5.88
5.89 # Store the result.
5.90 # NOTE: The data is considered ready to use.
5.91
5.92 - self.machine.save(addr + 1, -self.machine.load(left_data))
5.93 + self.machine.save(addr + self.instance_data_offset, -self.machine.load(left_data))
5.94
5.95 # Return the new object.
5.96 # Introduce object as context for the new object.
5.97 @@ -270,7 +267,7 @@
5.98 # Complete the list instance by saving the fragment reference.
5.99 # NOTE: This requires an attribute in the list structure.
5.100
5.101 - addr = list_value.ref + 1
5.102 + addr = list_value.ref + self.instance_data_offset
5.103 self.machine.save(addr, DataValue(None, new_fragment))
5.104
5.105 def builtins_list_get_single_item(self):
5.106 @@ -285,26 +282,25 @@
5.107 obj_value = self.frame_stack[frame]
5.108
5.109 # Get the fragment address.
5.110 - # NOTE: Assume single location for header.
5.111
5.112 - fragment = self.machine.load(obj_value.ref + 1)
5.113 + fragment = self.machine.load(obj_value.ref + self.instance_data_offset)
5.114
5.115 # Get the fragment header.
5.116
5.117 header = self.machine.load(fragment.ref)
5.118 nelements = header.occupied_size - 1
5.119
5.120 - # NOTE: Assume single location for data and header.
5.121 + # Get the item position.
5.122
5.123 - item_pos = self.machine.load(item_value.ref + 1)
5.124 + item_pos = self.machine.load(item_value.ref + self.instance_data_offset)
5.125
5.126 if not self._check_index(item_pos, nelements):
5.127 - self.machine.exception = self.machine._MakeObject(2, self.index_error_instance)
5.128 + self.machine.exception = self.machine._MakeObject(self.instance_size, self.index_error_instance)
5.129 return self.machine.RaiseException()
5.130
5.131 - # NOTE: Assume single location for header.
5.132 + # Get the item itself.
5.133
5.134 - self.machine.result = self.machine.load(fragment.ref + 1 + item_pos)
5.135 + self.machine.result = self.machine.load(fragment.ref + self.instance_data_offset + item_pos)
5.136
5.137 def builtins_list_len(self):
5.138 frame = self.local_sp_stack[-1]
5.139 @@ -314,9 +310,8 @@
5.140 obj_value = self.frame_stack[frame]
5.141
5.142 # Get the fragment address.
5.143 - # NOTE: Assume single location for header.
5.144
5.145 - fragment = self.machine.load(obj_value.ref + 1)
5.146 + fragment = self.machine.load(obj_value.ref + self.instance_data_offset)
5.147
5.148 # Get the fragment header.
5.149
5.150 @@ -325,12 +320,12 @@
5.151
5.152 # Make a new object.
5.153
5.154 - addr = self.machine._MakeObject(2, self.int_instance)
5.155 + addr = self.machine._MakeObject(self.instance_size, self.int_instance)
5.156
5.157 # Store the result.
5.158 # NOTE: The data is considered ready to use.
5.159
5.160 - self.machine.save(addr + 1, nelements)
5.161 + self.machine.save(addr + self.instance_data_offset, nelements)
5.162
5.163 # Return the new object.
5.164 # Introduce object as context for the new object.
5.165 @@ -349,9 +344,8 @@
5.166 obj_value = self.frame_stack[frame]
5.167
5.168 # Get the fragment address.
5.169 - # NOTE: Assume single location for header.
5.170
5.171 - fragment = self.machine.load(obj_value.ref + 1)
5.172 + fragment = self.machine.load(obj_value.ref + self.instance_data_offset)
5.173
5.174 # Get the fragment header.
5.175
5.176 @@ -379,7 +373,7 @@
5.177 # Set the new fragment in the object.
5.178 # NOTE: The old fragment could be deallocated.
5.179
5.180 - self.machine.save(obj_value.ref + 1, DataValue(None, new_fragment))
5.181 + self.machine.save(obj_value.ref + self.instance_data_offset, DataValue(None, new_fragment))
5.182
5.183 def builtins_tuple_len(self):
5.184 frame = self.local_sp_stack[-1]
5.185 @@ -389,19 +383,18 @@
5.186 obj_value = self.frame_stack[frame]
5.187
5.188 # Get the header.
5.189 - # NOTE: Assume single location for header.
5.190
5.191 header = self.machine.load(obj_value.ref)
5.192 - nelements = header.size - 1
5.193 + nelements = header.size - self.instance_data_offset
5.194
5.195 # Make a new object.
5.196
5.197 - addr = self.machine._MakeObject(2, self.int_instance)
5.198 + addr = self.machine._MakeObject(self.instance_size, self.int_instance)
5.199
5.200 # Store the result.
5.201 # NOTE: The data is considered ready to use.
5.202
5.203 - self.machine.save(addr + 1, nelements)
5.204 + self.machine.save(addr + self.instance_data_offset, nelements)
5.205
5.206 # Return the new object.
5.207 # Introduce object as context for the new object.
5.208 @@ -420,22 +413,21 @@
5.209 obj_value = self.frame_stack[frame]
5.210
5.211 # Get the header.
5.212 - # NOTE: Assume single location for header.
5.213
5.214 header = self.machine.load(obj_value.ref)
5.215 - nelements = header.size - 1
5.216 + nelements = header.size - self.instance_data_offset
5.217
5.218 # NOTE: Assume single location for data and header.
5.219
5.220 - item_pos = self.machine.load(item_value.ref + 1)
5.221 + item_pos = self.machine.load(item_value.ref + self.instance_data_offset)
5.222
5.223 if not self._check_index(item_pos, nelements):
5.224 - self.machine.exception = self.machine._MakeObject(2, self.index_error_instance)
5.225 + self.machine.exception = self.machine._MakeObject(self.instance_size, self.index_error_instance)
5.226 return self.machine.RaiseException()
5.227
5.228 - # NOTE: Assume single location for header.
5.229 + # Get the item.
5.230
5.231 - self.machine.result = self.machine.load(obj_value.ref + 1 + item_pos)
5.232 + self.machine.result = self.machine.load(obj_value.ref + self.instance_data_offset + item_pos)
5.233
5.234 def builtins_object_init(self):
5.235 pass