Skip to content

Instantly share code, notes, and snippets.

@thequux
Created May 11, 2014 19:17
Show Gist options
  • Save thequux/da1c572855485a89b2f5 to your computer and use it in GitHub Desktop.
Save thequux/da1c572855485a89b2f5 to your computer and use it in GitHub Desktop.
A sketch of a symbol table
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