1.1 --- a/micropython/data.py Fri Nov 06 01:07:48 2009 +0100
1.2 +++ b/micropython/data.py Fri Nov 06 01:17:07 2009 +0100
1.3 @@ -119,6 +119,14 @@
1.4 self.module = module
1.5 self.finalised = 0
1.6
1.7 + # Attributes accessed on objects, potentially narrowing their types.
1.8 + # Specific namespaces should define known names during initialisation.
1.9 +
1.10 + self.attributes_used = [{}] # stack of usage
1.11 + self.attribute_shelves = [] # stack of unmerged definitions
1.12 +
1.13 + # Attribute/name definition and access.
1.14 +
1.15 def __delitem__(self, name):
1.16 del self.namespace[name]
1.17
1.18 @@ -241,6 +249,8 @@
1.19 else:
1.20 return 0
1.21
1.22 + # Attribute positioning.
1.23 +
1.24 def attributes_as_list(self):
1.25
1.26 "Return the attributes in a list."
1.27 @@ -265,6 +275,52 @@
1.28
1.29 self.finalised = 1
1.30
1.31 + # Attribute usage methods.
1.32 +
1.33 + def _use_attribute(self, attr, attrname):
1.34 + name = attr.name
1.35 + defs = self.attributes_used[-1]
1.36 + if not defs.has_key(name):
1.37 + defs[name] = set()
1.38 + defs[name].add(attrname)
1.39 + return defs[name]
1.40 +
1.41 + def _reset_attributes(self, name):
1.42 + defs = self.attributes_used[-1]
1.43 + defs[name] = set()
1.44 +
1.45 + def _reset_all_attributes(self):
1.46 + self.attributes_used[-1] = {}
1.47 +
1.48 + def _new_branchpoint(self):
1.49 + self.attribute_shelves.append([])
1.50 +
1.51 + def _new_branch(self):
1.52 + d = {}
1.53 + for name, attrnames in self.attributes_used[-1].items():
1.54 + d[name] = set(attrnames)
1.55 + self.attributes_used.append(d)
1.56 +
1.57 + def _shelve_branch(self):
1.58 + self.attribute_shelves[-1].append(self.attributes_used.pop())
1.59 +
1.60 + def _merge_branches(self):
1.61 + active = self.attributes_used[-1]
1.62 +
1.63 + shelved_defs = self.attribute_shelves.pop()
1.64 + defs = shelved_defs[0]
1.65 +
1.66 + for next_defs in shelved_defs[1:]:
1.67 + for name, attrnames in next_defs.items():
1.68 + if defs.has_key(name):
1.69 + defs[name] = defs[name].intersection(attrnames)
1.70 +
1.71 + for name, attrnames in defs.items():
1.72 + if active.has_key(name):
1.73 + active[name] = active[name].intersection(attrnames)
1.74 + else:
1.75 + active[name] = attrnames
1.76 +
1.77 # Program data structures. There are two separate kinds of structures: those
1.78 # with context, which are the values manipulated by programs, and those without
1.79 # context, which are typically constant things which are stored alongside the
1.80 @@ -286,10 +342,6 @@
1.81 self.parent = parent
1.82 self.name = name
1.83
1.84 - # Attribute usage.
1.85 -
1.86 - self.attributes_used = set()
1.87 -
1.88 # Possible values.
1.89
1.90 self.context_values = set()
1.91 @@ -298,15 +350,6 @@
1.92
1.93 self.assignments = None
1.94
1.95 - # Attribute usage methods.
1.96 -
1.97 - def use_attribute(self, attrname):
1.98 - self.attributes_used.add(attrname)
1.99 - return self.attributes_used
1.100 -
1.101 - def exposes_name(self, attrname):
1.102 - return attrname in self.attributes_used
1.103 -
1.104 # Value-related methods.
1.105
1.106 def get_contexts(self):
1.107 @@ -808,8 +851,6 @@
1.108 name, pos = held.pop()
1.109 namearray[i] = name
1.110
1.111 - #print self.name, positions
1.112 - #print "->", namearray
1.113 return namearray
1.114
1.115 def _cmp_positions(self, a, b):
1.116 @@ -895,6 +936,11 @@
1.117
1.118 self.default_attrs = []
1.119
1.120 + # Initialise attribute usage.
1.121 +
1.122 + for arg in argnames:
1.123 + self.attributes_used[-1][arg] = set()
1.124 +
1.125 # Caches.
1.126
1.127 self.localnames = None # cache for locals