1.1 --- a/micropython/data.py Mon May 12 23:54:16 2008 +0200
1.2 +++ b/micropython/data.py Sun May 18 01:08:03 2008 +0200
1.3 @@ -46,6 +46,12 @@
1.4
1.5 from micropython.common import *
1.6
1.7 +def shortrepr(obj):
1.8 + if obj is None:
1.9 + return repr(None)
1.10 + else:
1.11 + return obj.__shortrepr__()
1.12 +
1.13 # Mix-ins and abstract classes.
1.14
1.15 class NamespaceDict:
1.16 @@ -104,9 +110,23 @@
1.17 "The underlying set operation associating 'name' with 'value'."
1.18
1.19 if not self.namespace.has_key(name):
1.20 - self.namespace[name] = Attr(None, self, name, value)
1.21 +
1.22 + # Attempt to fix the context.
1.23 +
1.24 + context = self._context(value)
1.25 + self.namespace[name] = Attr(None, self, context, name, value)
1.26 +
1.27 return self.namespace[name]
1.28
1.29 + def _context(self, value):
1.30 +
1.31 + "Return the context to be used when storing the given 'value'."
1.32 +
1.33 + if value is not None:
1.34 + return value.parent
1.35 + else:
1.36 + return None
1.37 +
1.38 def __delitem__(self, name):
1.39 del self.namespace[name]
1.40
1.41 @@ -158,11 +178,12 @@
1.42
1.43 class Attr:
1.44
1.45 - "An attribute entry having a parent as context."
1.46 + "An attribute entry having a context."
1.47
1.48 - def __init__(self, position, parent, name, value=None, assignments=None):
1.49 + def __init__(self, position, parent, context, name, value=None, assignments=None):
1.50 self.position = position
1.51 self.parent = parent
1.52 + self.context = context
1.53 self.name = name
1.54 self.value = value
1.55
1.56 @@ -194,8 +215,43 @@
1.57 self.assignments += AtLeast(1)
1.58 self.assignment_values.add(value)
1.59
1.60 + def via_instance(self):
1.61 +
1.62 + """
1.63 + Return either this attribute or a replacement where it is being accessed
1.64 + via an instance.
1.65 + """
1.66 +
1.67 + if self.context is not None:
1.68 +
1.69 + # Check compatibility of the context with the parent.
1.70 + # Where the attribute originates within the same hierarchy, use an
1.71 + # instance as the context.
1.72 +
1.73 + if isinstance(self.parent, Class) and isinstance(self.context, Class) and (
1.74 + self.context is self.parent or
1.75 + self.context in self.parent.descendants or
1.76 + self.parent in self.context.descendants):
1.77 +
1.78 + context = Instance()
1.79 +
1.80 + # Otherwise, preserve the existing context.
1.81 +
1.82 + else:
1.83 + context = self.context
1.84 +
1.85 + return Attr(self.position, self.parent, context, self.name, self.value, self.assignments)
1.86 +
1.87 + # Unknown contexts remain in use.
1.88 +
1.89 + else:
1.90 + return self
1.91 +
1.92 def __repr__(self):
1.93 - return "Attr(%r, %r, %r, %r, %r)" % (self.position, self.parent, self.name, self.value, self.assignments)
1.94 + return "Attr(%r, %s, %s, %r, %s, %r)" % (
1.95 + self.position, shortrepr(self.parent), shortrepr(self.context),
1.96 + self.name, shortrepr(self.value), self.assignments
1.97 + )
1.98
1.99 # Instances are special in that they need to be wrapped together with context in
1.100 # a running program, but they are not generally constant.
1.101 @@ -204,9 +260,14 @@
1.102
1.103 "A placeholder indicating the involvement of an instance."
1.104
1.105 + def __init__(self):
1.106 + self.parent = None
1.107 +
1.108 def __repr__(self):
1.109 return "Instance()"
1.110
1.111 + __shortrepr__ = __repr__
1.112 +
1.113 class Constant:
1.114
1.115 "A superclass for all constant or context-free structures."
1.116 @@ -230,6 +291,8 @@
1.117 else:
1.118 return "Const(%r)" % self.value
1.119
1.120 + __shortrepr__ = __repr__
1.121 +
1.122 # Support constants as dictionary keys in order to build constant tables.
1.123
1.124 def __eq__(self, other):
1.125 @@ -293,9 +356,25 @@
1.126
1.127 def __repr__(self):
1.128 if self.location is not None:
1.129 - return "Class(%r, %r, location=%r)" % (self.name, self.parent, self.location)
1.130 + return "Class(%r, %s, location=%r)" % (self.name, shortrepr(self.parent), self.location)
1.131 else:
1.132 - return "Class(%r, %r)" % (self.name, self.parent)
1.133 + return "Class(%r, %s)" % (self.name, shortrepr(self.parent))
1.134 +
1.135 + def __shortrepr__(self):
1.136 + return "Class(%r, %s)" % (self.name, shortrepr(self.parent))
1.137 +
1.138 + def _context(self, value):
1.139 +
1.140 + "Return the context to be used when storing the given 'value'."
1.141 +
1.142 + if value is not None:
1.143 + context = value.parent
1.144 + if isinstance(context, Module):
1.145 + return self
1.146 + else:
1.147 + return context
1.148 + else:
1.149 + return None
1.150
1.151 def finalise_attributes(self):
1.152
1.153 @@ -497,7 +576,7 @@
1.154
1.155 d = {}
1.156 for i, name in enumerate(self._get_position_list(positions)):
1.157 - d[name] = Attr(i, Instance(), name, None)
1.158 + d[name] = Attr(i, Instance(), None, name, None)
1.159 return d
1.160
1.161 def _cmp_positions(self, a, b):
1.162 @@ -607,16 +686,21 @@
1.163
1.164 def __repr__(self):
1.165 if self.location is not None:
1.166 - return "Function(%r, %r, %r, %r, %r, %r, location=%r)" % (
1.167 - self.name, self.parent, self.argnames, self.defaults, self.has_star, self.has_dstar, self.location
1.168 + return "Function(%r, %s, %r, %r, %r, %r, location=%r)" % (
1.169 + self.name, shortrepr(self.parent), self.argnames, self.defaults, self.has_star, self.has_dstar, self.location
1.170 )
1.171 else:
1.172 - return "Function(%r, %r, %r, %r, %r, %r)" % (
1.173 - self.name, self.parent, self.argnames, self.defaults, self.has_star, self.has_dstar
1.174 + return "Function(%r, %s, %r, %r, %r, %r)" % (
1.175 + self.name, shortrepr(self.parent), self.argnames, self.defaults, self.has_star, self.has_dstar
1.176 )
1.177
1.178 + def __shortrepr__(self):
1.179 + return "Function(%r, %s)" % (
1.180 + self.name, shortrepr(self.parent)
1.181 + )
1.182 +
1.183 def store_default(self, value):
1.184 - attr = Attr(None, self, None, value)
1.185 + attr = Attr(None, self, None, None, value)
1.186 attr.update(value, 1)
1.187 self.default_attrs.append(attr)
1.188
1.189 @@ -689,15 +773,15 @@
1.190 self[name].position = i
1.191
1.192 if i is not None:
1.193 - j = i
1.194 + j = i + 1
1.195 else:
1.196 j = 0
1.197
1.198 - i = -1
1.199 + i = 0
1.200 for i, attr in enumerate(self.locals().values()):
1.201 attr.position = i + j
1.202
1.203 - self.stack_local_usage = i + 1
1.204 + self.stack_local_usage = i
1.205
1.206 def function_from_method(self):
1.207
1.208 @@ -726,6 +810,8 @@
1.209 def __repr__(self):
1.210 return "UnresolvedName(%r, %r)" % (self.name, self.parent_name)
1.211
1.212 + __shortrepr__ = __repr__
1.213 +
1.214 def full_name(self):
1.215 if self.name is not None:
1.216 return self.parent_name + "." + self.name
1.217 @@ -772,6 +858,9 @@
1.218 else:
1.219 return "Module(%r)" % self.name
1.220
1.221 + def __shortrepr__(self):
1.222 + return "Module(%r)" % self.name
1.223 +
1.224 # Attribute methods.
1.225
1.226 "Return the module attribute names provided by the module."