I'm attempting to write a small compiler for a mini language called minijava, in order to gain insight in compiler construction and functional programming. My current implementation is in Scala, a language which I'm also just starting to learn.
sealed class Record()
case object Usage extends Record
case class Declaration(
definition: Term,
typ: Type
) extends Record
class Scope(
val parent: Option[ Scope ],
val scopes: List[ Namespace ],
// represents the actual (local) symbol-table
val symbols: Map[ (Namespace, String), Record ] = new HashMap()
) extends Immutable {
def add( ns: Namespace, id: String, record: Record ): Scope =
new Scope(parent, scopes, symbols + Tuple2((ns, id), record ))
def enter_scope(scopes: List[ Namespace ]) = new Scope( Some(this), scopes )
def leave_scope() = parent
}
Now I can construct a symbol table using this class by going over the AST, and constructing a tree of scopes. This can be done nicely using pattern matching, and functional programming in scala makes sense this way.
However, I need to keep track of the scope that an AST node belongs to in order to make this thing useful... So I'd like to somehow wrap this thing in order to build a hashmap of nodes to scopes everytime I add a declaration.
I've considered many patterns, but I can't find a way to do this that is:
- functional
- without mutable state
- nice (i.e. does not make me write stuff feels redundant)
Can anyone come up with something nice?