class Environment: def __init__(self, parent): self.parent = parent # pointer to parent environment self.map = {} # 2D map containing namespaces and names under them # add name to Env def addName(self, name, namespace, node): if namespace in self.map and name in self.map[namespace]: raise IOException if namespace in self.map: self.map[namespace][name] = node else: self.map[namespace] = {name: node} # returns AST node that is associate with the name, None if name is not defined def getDef(self, name): if name not in self.map: if not self.parent: raise IOException return self.parent.getDef(name) return self.map[name] ################################################### # base class for all ASTNodes # define some basic operation for overriding later class ASTNode: def __init__(self, parseTree, parentEnv): self.parseTree = parseTree # stores the parse tree in case we want to do sth later self.env = parentEnv def nameResolv(self): for n in self.names: n = self.env.getDef(n) class ScopeNode(ASTNode): def __init__(self, parseTree, parentEnv): super().__init__(parseTree, parentEnv) self.env = Environment(parentEnv) for n in parseTree.children: if n.name == 'ID': self.name = n.lex break