1.1 --- a/micropython/data.py Wed Feb 10 01:25:48 2010 +0100
1.2 +++ b/micropython/data.py Fri Feb 12 01:34:28 2010 +0100
1.3 @@ -125,10 +125,10 @@
1.4
1.5 self.attributes_used = [{}] # stack of usage
1.6 self.attribute_shelves = [] # stack of unmerged definitions
1.7 + self.abandon_attributes = 0 # used when a block will never contribute
1.8 + self.abandoned_shelves = []
1.9 self.attribute_users = [{}] # stack of assignments
1.10 - self.abandon_attributes = 0 # used when a block will never contribute
1.11 - self.attributes_abandoned = [{}]
1.12 - self.abandoned_shelves = []
1.13 + self.user_shelves = []
1.14 self.all_attributes_used = []
1.15
1.16 # Attribute/name definition and access.
1.17 @@ -310,7 +310,7 @@
1.18 def _use_attribute(self, name, attrname):
1.19
1.20 """
1.21 - Indicate the use on the given 'name' in this namespace of an attribute
1.22 + Indicate the use of the given 'name' in this namespace of an attribute
1.23 with the given 'attrname'.
1.24 """
1.25
1.26 @@ -325,6 +325,13 @@
1.27 defs[name] = set()
1.28
1.29 defs[name].add(attrname)
1.30 +
1.31 + # Add the usage to all current users.
1.32 +
1.33 + if users.has_key(name):
1.34 + for user in users[name]:
1.35 + user._attrnames[name].add(attrname)
1.36 +
1.37 return defs[name]
1.38
1.39 def _define_attribute_user(self, node):
1.40 @@ -342,21 +349,20 @@
1.41 "Define 'node' as the user of attributes for the given 'name'."
1.42
1.43 defs = self.attributes_used[-1]
1.44 - abandoned_defs = self.attributes_abandoned[-1]
1.45 users = self.attribute_users[-1]
1.46
1.47 - users[name] = node
1.48 + users[name] = set([node])
1.49 defs[name] = set()
1.50 - abandoned_defs[name] = set()
1.51
1.52 # Record the attribute combinations for the name.
1.53
1.54 if not hasattr(node, "_attrnames"):
1.55 node._attrnames = {}
1.56 - node._attrnames_abandoned = {}
1.57
1.58 - node._attrnames[name] = defs[name]
1.59 - node._attrnames_abandoned[name] = abandoned_defs[name]
1.60 + # Copy the current usage for the user since this may eventually become
1.61 + # independent from the current usage.
1.62 +
1.63 + node._attrnames[name] = set(defs[name])
1.64
1.65 # Remember all attribute combinations.
1.66
1.67 @@ -365,12 +371,16 @@
1.68 def _new_branchpoint(self):
1.69 self.attribute_shelves.append([])
1.70 self.abandoned_shelves.append([])
1.71 + self.user_shelves.append([])
1.72
1.73 def _new_branch(self):
1.74 d = {}
1.75 for name, attrnames in self.attributes_used[-1].items():
1.76 d[name] = set(attrnames)
1.77 self.attributes_used.append(d)
1.78 +
1.79 + # The users apply also to the new branch.
1.80 +
1.81 self.attribute_users.append({})
1.82
1.83 def _abandon_branch(self):
1.84 @@ -393,9 +403,13 @@
1.85 collector.append(self.attributes_used.pop())
1.86
1.87 # Forget about any nodes which defined names employing attributes in
1.88 - # this branch.
1.89 + # this branch if the branch is abandoned.
1.90 +
1.91 + users = self.attribute_users.pop()
1.92
1.93 - self.attribute_users.pop()
1.94 + if not self.abandon_attributes:
1.95 + self.user_shelves[-1].append(users)
1.96 +
1.97 self.abandon_attributes = 0
1.98
1.99 def _merge_branches(self):
1.100 @@ -414,7 +428,6 @@
1.101 # branches. The abandoned dictionary collects abandoned usage.
1.102
1.103 active = self.attributes_used[-1]
1.104 - abandoned = self.attributes_abandoned[-1]
1.105
1.106 # Take each alternative branch, currently shelved, and find the
1.107 # intersection of their contributions for each name.
1.108 @@ -441,16 +454,13 @@
1.109 else:
1.110 active[name] = attrnames
1.111
1.112 - # Where abandoned branches exist, record their contributions for the
1.113 - # attribute users only.
1.114 + # Combine the attribute users.
1.115 +
1.116 + users = self.attribute_users[-1]
1.117
1.118 - if abandoned_defs:
1.119 - for defs in abandoned_defs:
1.120 - for name, attrnames in defs.items():
1.121 - if abandoned.has_key(name):
1.122 - abandoned[name].add(tuple(attrnames))
1.123 - else:
1.124 - abandoned[name] = attrnames
1.125 + for shelved_users in self.user_shelves.pop():
1.126 + for name, nodes in shelved_users.items():
1.127 + users[name].update(nodes)
1.128
1.129 # Where each shelved set of definitions is a superset of the eventual
1.130 # definitions for a name, record these specialised sets of usage.