AST walker

A `collections.defaultdict` would make this cleaner. But be careful with the semantics (i.e. you may want the `KeyError`s elsewhere).