diff --git a/ASTNode.py b/ASTNode.py index 11e80e77e40dbd78be7a4ebdf0a283a0b6d32b22..27bf41d8ec432d2d98948af0f7bb1fee3dc4a538 100644 --- a/ASTNode.py +++ b/ASTNode.py @@ -1,10 +1,34 @@ -from Environment import Environment + +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 = parseNode # stores the parse tree in case we want to do sth later + self.parseTree = parseTree # stores the parse tree in case we want to do sth later self.env = parentEnv def nameResolv(self): @@ -18,4 +42,8 @@ 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 diff --git a/Environment.py b/Environment.py index 81fe9b994a56c4f0d577e335c3d330f3cf0e44ec..dd042610fa6441c0256e8361c1dfeb9222e19ce4 100644 --- a/Environment.py +++ b/Environment.py @@ -1,57 +1,56 @@ -class Enviroment: - def __init__(self, parent): - self.parent = parent # pointer to parent environment - self.map = {} # 2D map containing namespaces and names under them +from ASTNode import ScopeNode, Environment - # 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] - ################################################################## # give a list of parseTrees, returns the global Environemnt object and # a list of classNodes with globalEnv attached to them def buildGlobalEnv(parseTrees): - gEnv = Enviroment(None) + gEnv = Environment(None) ASTs = [] for t in parseTrees: # add imports imports = getParseTreeNodes(['importDcl'], t) for i in imports: - importNames = getParseTreeNodes(['ID', 'COMPID', 'IMPORTALL']) + importNames = getParseTreeNodes(['ID', 'COMPID', 'IMPORTALL'], i) for n in importNames: gEnv.addName(n.lex, 'package', None) + # TODO: figure out package name + packages = getParseTreeNodes('packageDcl', t) + pNames = [] + for p in packages: + pNames.extend(getParseTreeNodes(['ID', 'COMPID'], p)) + if pNames: + pNames = pNames[0] + else: + pNames = 'no packageName' + # add class to global Env - packageName = getParseTreeNodes('packageDcl', t) classDcl = getParseTreeNodes('classDcl', t) interfaceDcl = getParseTreeNodes('interfaceDcl', t) if not classDcl: - intNode = InterfaceNode(interfaceDcl[0], gEnv) + intNode = ScopeNode(interfaceDcl[0], gEnv) ASTs.append(intNode) - gEnv.addName(intNode.name, 'interface', intNode) + gEnv.addName(pNames+ " " + intNode.name, 'interface', intNode) else: - classNode = ClassNode(classDcl[0], gEnv) + classNode = ScopeNode(classDcl[0], gEnv) ASTs.append(classNode) - gEnv.addName(classNode.name, 'class', classNode) + gEnv.addName(pNames+ " " + classNode.name, 'class', classNode) + + #prints + print('----------- global env ------------') + for g in gEnv.map: + print(g) + for gg in gEnv.map[g]: + print(gg) + print('----------- ASTs -----------------') + for a in ASTs: + print(a.name) return gEnv, ASTs # Utils: given a parseTree and a list of names, traverse the tree