| 23 | |
| 24 | |
| 25 | class Symbols(object): |
| 26 | |
| 27 | def __init__(self, parent=None, level=None): |
| 28 | if level is None: |
| 29 | if parent is None: |
| 30 | level = 0 |
| 31 | else: |
| 32 | level = parent.level + 1 |
| 33 | self.level = level |
| 34 | self.parent = parent |
| 35 | self.refs = {} |
| 36 | self.loads = {} |
| 37 | self.stores = set() |
| 38 | |
| 39 | def analyze_node(self, node, **kwargs): |
| 40 | visitor = RootVisitor(self) |
| 41 | visitor.visit(node, **kwargs) |
| 42 | |
| 43 | def _define_ref(self, name, load=None): |
| 44 | ident = 'l_%d_%s' % (self.level, name) |
| 45 | self.refs[name] = ident |
| 46 | if load is not None: |
| 47 | self.loads[ident] = load |
| 48 | return ident |
| 49 | |
| 50 | def find_load(self, target): |
| 51 | if target in self.loads: |
| 52 | return self.loads[target] |
| 53 | if self.parent is not None: |
| 54 | return self.parent.find_load(target) |
| 55 | |
| 56 | def find_ref(self, name): |
| 57 | if name in self.refs: |
| 58 | return self.refs[name] |
| 59 | if self.parent is not None: |
| 60 | return self.parent.find_ref(name) |
| 61 | |
| 62 | def ref(self, name): |
| 63 | rv = self.find_ref(name) |
| 64 | if rv is None: |
| 65 | raise AssertionError('Tried to resolve a name to a reference that ' |
| 66 | 'was unknown to the frame (%r)' % name) |
| 67 | return rv |
| 68 | |
| 69 | def copy(self): |
| 70 | rv = object.__new__(self.__class__) |
| 71 | rv.__dict__.update(self.__dict__) |
| 72 | rv.refs = self.refs.copy() |
| 73 | rv.loads = self.loads.copy() |
| 74 | rv.stores = self.stores.copy() |
| 75 | return rv |
| 76 | |
| 77 | def store(self, name): |
| 78 | self.stores.add(name) |
| 79 | |
| 80 | # If we have not see the name referenced yet, we need to figure |
| 81 | # out what to set it to. |
| 82 | if name not in self.refs: |
no outgoing calls
no test coverage detected