I fixed a couple pretty fundamental name resolution bugs today. The main reason they happened is because there are currently three places names are resolved: the parser, the binder, and the typechecker.
The typechecker is the one name resolution stage that is definitely required. For example, there is no way to resolve a class member until we know what type of object it is, especially for something like foo.bar.baz.member. We must know the type of baz before we can resolve what name member is pointing to; there really isn't any other way.
It is also reasonably rational to have a binding stage in the parser. This lets us easily handle things like variable shadowing. Maybe more specifically, the parser gives a very natural static binding--literally a syntax-directed static binding--and this is a pretty predictable binding rule, so it makes sense to do it in the parser.
So, it could be reasonable to just ditch the Binder stage entirely. Almost all of its logic could likely be moved to TypeChecker, which would save maybe about 400 lines of code right now, but more importantly reduce (sort of) the number of places that name resolution happens.
I'm not entirely sure. It is something to consider.
I fixed a couple pretty fundamental name resolution bugs today. The main reason they happened is because there are currently three places names are resolved: the parser, the binder, and the typechecker.
The typechecker is the one name resolution stage that is definitely required. For example, there is no way to resolve a class member until we know what type of object it is, especially for something like
foo.bar.baz.member. We must know the type ofbazbefore we can resolve what namememberis pointing to; there really isn't any other way.It is also reasonably rational to have a binding stage in the parser. This lets us easily handle things like variable shadowing. Maybe more specifically, the parser gives a very natural static binding--literally a syntax-directed static binding--and this is a pretty predictable binding rule, so it makes sense to do it in the parser.
So, it could be reasonable to just ditch the Binder stage entirely. Almost all of its logic could likely be moved to TypeChecker, which would save maybe about 400 lines of code right now, but more importantly reduce (sort of) the number of places that name resolution happens.
I'm not entirely sure. It is something to consider.