From 4c111a8d97793ef0e5003a0abf20f3cddd198172 Mon Sep 17 00:00:00 2001 From: Nicholas Robinson <nwrobins@edu.uwaterloo.ca> Date: Sat, 7 Mar 2020 03:30:52 -0500 Subject: [PATCH] a2 GlobalEnv:getNode fixes - show elapsed time in Test.py - GlobalEnv no more '.' in front of types without a package - lots of GlobalEnv:getNode fixes - fixing but still testing GlobalEnv:weedGlobalEnv - cleaned up some comments --- AstBuilding.py | 9 +------ Environment.py | 71 +++++++++++++++++++++++++++++++++++++------------- Test.py | 8 +++--- 3 files changed, 59 insertions(+), 29 deletions(-) diff --git a/AstBuilding.py b/AstBuilding.py index 5a8bb39..035a8f9 100644 --- a/AstBuilding.py +++ b/AstBuilding.py @@ -32,13 +32,10 @@ def buildEnvAndLink(ASTs): # type Linking - # print('--------->>> type linking time!') for t in ASTs: - # t[1].buildEnvFromImports(globalEnv) t[1].recurseAction("linkType") # hierarchy checking - # print('--------->>> hierarchy checking time!') for t in ASTs: t[1].recurseAction("checkHierarchy") @@ -46,12 +43,8 @@ def buildEnvAndLink(ASTs): def disamiguateAndTypeChecking(ASTs): - # disambiguate namesapce: figuring out the meaning of the shortest prefix of names + # disambiguate namespace: figuring out the meaning of the shortest prefix of names for t in ASTs: - # try: - # t[1].recurseAction("disambigName") - # except Exception as e: - # raise e t[1].disambigName() # type checking diff --git a/Environment.py b/Environment.py index 921ec8e..5e0ecdb 100644 --- a/Environment.py +++ b/Environment.py @@ -79,9 +79,11 @@ class GlobalEnv(Env): namespace = self.nodeToNamespace.get(typeDclType) # Add to map - mapKey = pName + '.' + typeDcl.name + mapKey = pName + '.' + typeDcl.name + if not pName: + mapKey = typeDcl.name if mapKey in self.map: - raise Exception('ERROR: Declaration of {} is already in current Environment'.format(pName + '.' + typeDcl.name)) + raise Exception('ERROR: Declaration of {} is already in current Environment'.format(mapKey)) self.map[mapKey] = typeDcl # Add to packageMap @@ -90,52 +92,85 @@ class GlobalEnv(Env): self.packageMap[pName] = {} if pMapKey in self.packageMap[pName]: - raise Exception('ERROR: Declaration of {} is already in current Environment'.format(pName + '.' + typeDcl.name)) + raise Exception('ERROR: Declaration of {} is already in current Environment'.format(mapKey)) self.packageMap[pName][pMapKey] = typeDcl def weedGlobalEnv(self): # call after building global Env to resolve clashes: + # TODO crashing some A2 tests + + # from pprint import pprint + # print('self.map') + # pprint(self.map) + # print('self.packageMap') + # pprint(self.packageMap) + # pprint(self.packageMap.keys()) + for i in self.map.keys(): for j in self.packageMap.keys(): - if i in j: + iNode = self.map.get(i) + # if j == "java.util.ArrayList.foo" and "java.util.ArrayList.foo" in i: + # print('j ', j) + # print('i ', i) + # print('iNode.packageName ', iNode.packageName) + # i.rpartition('.')[0] == j + if i in j and iNode.packageName: + # print('i ({}) is in j ({})'.format(i,j)) raise Exception('ERROR: Package name {} clashing with Type name {}'.format(j, i)) # Use getNode() from base class to get node using Canonical Name (full name) def getNode(self, key, imported, packageName): - # TODO: error if ambiguous - # TODO: not sure whether name is canonical or not???? - # i.e. there are more than one of this type. Currently it only gets the first occurence name = key[0] + found = [] # list of found nodes # 1. enclosing class/interface # - already did + # fully qualified name (canonName) if name in self.map: return self.map.get(name) + # 2. single-type import (simple Name) for i in imported: if not '*' in i: - simpleName = i.split(".")[-1] - if simpleName == name: - return self.map.get(i) + full = i.split(".")[-1] + if full == name: + found.append(self.map.get(i)) + # 3. type in the current package full = packageName + '.' + name - # print(full) if full in self.map: return self.map.get(full) + # 4. import-on-demand + checked = [] for i in imported: - if '*' in i: + if '*' in i and i not in checked: + checked.append(i) full = i.replace("*", name) if full in self.map: - return self.map.get(full) + found.append(self.map.get(full)) + # imported implicitly: java.io.*, java.lang.*, java.util.* - implicitly = ['java.lang.', 'java.io.', 'java.util.'] + implicitly = ['java.lang.'] + + # remove from implicitly if we are in that package already + if (packageName + '.') in implicitly: + implicitly.remove(packageName + '.') + + # remove from implicitly if we explicitly imported it + for i in imported: + if '*' in i and i.replace("*", "") in implicitly: + implicitly.remove(i.replace("*", "")) + for i in implicitly: - if i in name and name in self.map: - return self.map.get(name) - elif (i+name) in self.map: - return self.map.get(i+name) + if (i+name) in self.map: + found.append(self.map.get(i+name)) + + if len(found) == 1: + return found[0] + elif len(found) > 1: + raise Exception("ERROR: Trying to access ambiguous name '{}' in the Environment".format(key)) raise Exception("ERROR: Can't find definition of {} in the Environment".format(key)) diff --git a/Test.py b/Test.py index 0a43495..0dec390 100644 --- a/Test.py +++ b/Test.py @@ -1,4 +1,5 @@ import sys +import time from os import listdir, scandir, walk from os.path import isfile, join import traceback @@ -43,6 +44,7 @@ def a2Multiple(): total = 0 correct = 0 + start = time.time() for c in testCases: # get all files from stdlib folder @@ -73,9 +75,9 @@ def a2Multiple(): else: correct += 1 - print("\nSCORE: {} / {} -> {:.3g}%".format(correct, total, (correct/total)*100)) - - + end = time.time() + print("\nTime Elapsed: {}".format(time.strftime('%H:%M:%S', time.gmtime(end - start)))) + print("SCORE: {} / {} -> {:.3g}%".format(correct, total, (correct/total)*100)) def run(testFiles): parseTrees = [] -- GitLab