1.1 --- a/micropython/data.py Sun Oct 25 18:35:53 2009 +0100
1.2 +++ b/micropython/data.py Sat Oct 31 22:59:35 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,48 @@
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 +
1.40 + def _reset_attributes(self, name):
1.41 + defs = self.attributes_used[-1]
1.42 + defs[name] = set()
1.43 +
1.44 + def _new_branchpoint(self):
1.45 + self.attribute_shelves.append([])
1.46 +
1.47 + def _new_branch(self):
1.48 + d = {}
1.49 + for name, attrnames in self.attributes_used[-1].items():
1.50 + d[name] = set(attrnames)
1.51 + self.attributes_used.append(d)
1.52 +
1.53 + def _shelve_branch(self):
1.54 + self.attribute_shelves[-1].append(self.attributes_used.pop())
1.55 +
1.56 + def _merge_branches(self):
1.57 + active = self.attributes_used[-1]
1.58 +
1.59 + shelved_defs = self.attribute_shelves.pop()
1.60 + defs = shelved_defs[0]
1.61 +
1.62 + for next_defs in shelved_defs[1:]:
1.63 + for name, attrnames in next_defs.items():
1.64 + if defs.has_key(name):
1.65 + defs[name].intersection_update(attrnames)
1.66 +
1.67 + for name, attrnames in defs.items():
1.68 + if active.has_key(name):
1.69 + active[name].intersection_update(attrnames)
1.70 + else:
1.71 + active[name] = attrnames
1.72 +
1.73 # Program data structures. There are two separate kinds of structures: those
1.74 # with context, which are the values manipulated by programs, and those without
1.75 # context, which are typically constant things which are stored alongside the
1.76 @@ -286,6 +338,8 @@
1.77 self.parent = parent
1.78 self.name = name
1.79
1.80 + # Possible values.
1.81 +
1.82 self.context_values = set()
1.83
1.84 # Number of assignments per name.
1.85 @@ -791,8 +845,6 @@
1.86 name, pos = held.pop()
1.87 namearray[i] = name
1.88
1.89 - #print self.name, positions
1.90 - #print "->", namearray
1.91 return namearray
1.92
1.93 def _cmp_positions(self, a, b):
1.94 @@ -878,6 +930,11 @@
1.95
1.96 self.default_attrs = []
1.97
1.98 + # Initialise attribute usage.
1.99 +
1.100 + for arg in argnames:
1.101 + self.attributes_used[-1][arg] = set()
1.102 +
1.103 # Caches.
1.104
1.105 self.localnames = None # cache for locals