Created
May 11, 2014 19:17
-
-
Save thequux/da1c572855485a89b2f5 to your computer and use it in GitHub Desktop.
A sketch of a symbol table
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import collections | |
import contextlib | |
import itertools | |
class SymbolTable(collections.MutableMapping): | |
__slots__ = ('_content') | |
def __init__(self): | |
self._content = [] | |
def _top_dict(self): | |
if not self._content: | |
self._content.push({}) | |
return self._content[-1] | |
# Getters and setters | |
def __getitem__(self, key): | |
for d in reversed(self._content): # start with the last one pushed | |
if key in d: | |
return d[key] | |
else: | |
raise KeyError("Symbol %s not found" % repr(key)) | |
def __setitem__(self, key, value): | |
d = self._top_dict() | |
if key in d: # change d to self to not allow dynamic overrides | |
raise KeyError("Can't redefine key %s" % repr(key)) | |
d[key] = value | |
def __iter__(self, key, value): | |
seen_keys = set() | |
for d in reversed(self._content): | |
for k in d: | |
if k not in seen_keys: | |
seen_keys.add(k) | |
yield k | |
def __len__(self): | |
return itertools.count(self) | |
# Context management; use like | |
# with table.scope(): | |
# # ... blah blah blah | |
@contextlib.contextmanager | |
def scope(self): | |
self._content.push(dict()) | |
yield | |
self._content.pop() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment