The programming language you are implementing will for sure define exact rules for name resolution. I don't think it will lead to a depth-first search. Name resolution rules, very fruequently, look somethink like this:
- search the current scope, frequently considering only what has been declared “up” from the current position in the source code;
- when some specific rules are met, e.g. there is some form of a
using
/import
or whatever other construct linking to some other scope, perform a search in that other scope (all of such scopes, sequentially), and recurse within it:- search the given scope,
- recurse for any relevant nested scopes;
- go to the immediatelly enclosing scope;
- repeat from (1), where the 'current' scope is that determined in (3).
In other words, you gradually go up in the tree of enclosing scopes, and decide whether to search any 'foreign' referenced scopes. Statements such as using
/ import
lead to references among scopes, which in turn cause what is viewed as a tree of scopes to be in fact a directed graph.
Regarding the lookup table construction, I'd start with a simple hashtable. Prefix trees (tries) work well for these scenarios, too.
Last but not least, I wouldn't care much of lookup performance unless I'd face a real performance problem when compiling tens or maybe hundreds of thousands of lines of code.