Skip to content
Snippets Groups Projects
Commit 9d05dc14 authored by pycsham's avatar pycsham
Browse files

fixed some expr node errors

parents 66a1234d 374e5212
No related branches found
No related tags found
No related merge requests found
......@@ -31,6 +31,9 @@ class ASTNode():
self.env = parentEnv
return parentEnv
def linkType(self):
pass
def printNodePretty(self, prefix=0):
pp = pprint.PrettyPrinter(indent=prefix)
pp.pprint(self.__class__.__name__)
......@@ -63,7 +66,8 @@ class ASTNode():
def getParseTreeNodes(names, tree, terminateList = []):
result = []
if tree.name in names:
return result.append(tree)
result.append(tree)
return result
if not tree.children:
return []
for n in tree.children:
......
......@@ -24,10 +24,11 @@ def buildEnvAndLink(ASTs):
print("###################### Comp Unit Env ####################")
t[1].recurseAction("printEnv")
# # type Linking
# for t in ASTs:
# t.buildEnvFromImports(globalEnv)
# # t.typeDcl.recurseAction("linkType")
# type Linking
print('--------->>> type linking time!')
for t in ASTs:
# t[1].buildEnvFromImports(globalEnv)
t[1].recurseAction("linkType")
#######################################################
......
from AST import ASTNode, getParseTreeNodes
from TypeNodes import InterNode, ClassNode
from Environment import Env
from Environment import Env, CompEnv
# compilation unit
class CompNode(ASTNode):
......@@ -34,8 +34,8 @@ class CompNode(ASTNode):
self.children.append(self.typeDcl)
def buildEnv(self, parentEnv):
env = Env(None) # global environment is not the parent Env, each file don't have access to all the stuff in global env
env.addtoEnv(self.typeDcl)
env = CompEnv(parentEnv, self.importNames, self.packageName)
# env.addtoEnv(self.typeDcl)
# # add imports
# for i in self.importNames:
# pName = i.split('.*') # check if it's import all
......
......@@ -45,8 +45,8 @@ class Env:
if key in self.map:
return self.map.get(key)
elif parentEnv:
return parentEnv.getNode(name, namespace)
elif self.parentEnv:
return self.parentEnv.getNode(name, namespace)
raise Exception("ERROR: Can't find definition of {} in the Environment".format(name))
###################################
......@@ -55,7 +55,7 @@ class GlobalEnv(Env):
def __init__(self):
super().__init__(None)
#self.map = {} # {Canonical name -> node}
self.pacakgeMap = {} # {packageName -> {(simpleName, namespace) -> node}}
self.packageMap = {} # {packageName -> {(simpleName, namespace) -> node}}
# A map of maps
# contains duplicate info as self.map for easy searching
......@@ -75,25 +75,55 @@ class GlobalEnv(Env):
# Add to packageMap
pMapKey = (typeDcl.name, namespace)
if not pName in self.pacakgeMap:
self.pacakgeMap[pName] = {}
if not pName in self.packageMap:
self.packageMap[pName] = {}
if pMapKey in self.pacakgeMap[pName]:
if pMapKey in self.packageMap[pName]:
raise Exception('ERROR: Declaration of {} is already in current Environment'.format(pName + '.' + typeDcl.name))
self.pacakgeMap[pName][pMapKey] = typeDcl
self.packageMap[pName][pMapKey] = typeDcl
# Use getNode() from base class to get node using Canonical Name (full name)
def getNode(self, name): # since all names in global namespace is in namespace type
key = name
if key in self.map:
return self.map.get(key)
elif parentEnv:
return parentEnv.getNode(name, namespace)
raise Exception("ERROR: Can't find definition of {} in the Environment".format(name))
def getNode(self, key, imported, packageName):
name = key[0]
# 1. enclosing class/interface
# - already did
# 2. single-type import
if name in imported:
if name in self.map:
return self.map.get(name)
# 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
for i in imported:
if '*' in i:
full = i.replace("*", name)
if full in self.map:
return self.map.get(full)
raise Exception("ERROR: Can't find definition of {} in the Environment".format(key))
# method for getting all the nodes under a package (import All)
# returns a dict of types under that package name
def getNodesByPackage(self, pName):
if not pName in self.pacakgeMap:
if not pName in self.packageMap:
raise Exception("ERROR: Can't find definition of package {} in the Environment".format(pName))
return self.pacakgeMap.get(pName)
return self.packageMap.get(pName)
###################################
class CompEnv(Env):
def __init__(self, parentEnv, imported, packageName):
super().__init__(parentEnv) # globalEnv is parentEnv
self.imported = imported # list of strings that have been imported in this comp
self.packageName = packageName # string of the current file's package name
def getNode(self, name, namespace):
key = (name, namespace)
if key in self.map:
return self.map.get(key)
elif self.parentEnv: # globalEnv
return self.parentEnv.getNode(key, self.imported, self.packageName)
raise Exception("ERROR: Can't find definition of {} in the Environment".format(name))
\ No newline at end of file
......@@ -25,7 +25,7 @@ def makeNodeFromExpr(parseTree):
c = parseTree
while (42):
if c.name == 'primaryAndArray':
return makeNodeFromAllPrimary(c.children[0])
return makeNodeFromAllPrimary(c)
elif c.name == 'ID' or c.name == 'COMPID':
return c.lex
elif c.name == 'assignment':
......@@ -41,9 +41,13 @@ def makeNodeFromExpr(parseTree):
def makeNodeFromAllPrimary(parseTree):
if parseTree.name == 'primaryAndArray':
if parseTree.children[0].name == 'arrayCreationExpr':
return ArrayCreateNode(parseTree.children[0])
parseTree = parseTree.children[0]
parseTree = parseTree.children[0]
return ArrayCreateNode(parseTree)
elif parseTree.children[0].name == 'primary':
if parseTree.children[0].children[0].name == 'arrayAccess':
return ArrayAccessNode(parseTree.children[0].children[0])
parseTree = parseTree.children[0].children[0]
if parseTree.name == 'primary':
if parseTree.children[0].name == 'arrayAccess':
return ArrayAccessNode(parseTree.children[0])
......@@ -233,9 +237,9 @@ class MethodInvNode(ASTNode):
self.env = None
self.children = []
# input parse tree is either: arrayAccess name LSQRBRACK expr RSQRBRACK
# arrayAccess ID LSQRBRACK expr RSQRBRACK
# arrayAccess primaryNoArrayAccess LSQRBRACK expr RSQRBRACK
# input parse tree is either: methodInvoc primary PERIOD ID LPAREN args RPAREN
# methodInvoc name LPAREN args RPAREN
# methodInvoc ID LPAREN args RPAREN
self.ID = getParseTreeNodes(['ID', 'COMPID'], parseTree.children[-4])[0].lex
self.args = ArgsNode(parseTree.children[-2])
if parseTree.children[0].name == 'primary':
......
......@@ -210,7 +210,7 @@ class ForNode(ASTNode):
self.forBound = makeNodeFromExpr(node.children[0])
elif node.name == 'statement' ofr node.name == 'statementNoShortIf':
elif node.name == 'statement' or node.name == 'statementNoShortIf':
self.bodyStatement = makeNodeFromAllStatement(node)
self.children.append(self.forInit)
......
from AST import ASTNode, getParseTreeNodes
# from LineNodes import BlockNode
from LineNodes import BlockNode, VarDclNode
from ExprPrimaryNodes import makeNodeFromExpr
from UnitNodes import TypeNode, ParamNode
from Environment import Env
......@@ -25,8 +25,8 @@ class FieldNode(ASTNode):
elif node.name == 'type':
self.fieldType = TypeNode(node)
# elif node.name == 'variableDcl':
# self.variableDcl = VarDclNode(node)
elif node.name == 'variableDcl':
self.variableDcl = VarDclNode(node)
self.children.append(self.variableDcl)
......@@ -72,8 +72,8 @@ class MethodNode(ASTNode):
elif node.name == 'methodBody':
nameNodes = getParseTreeNodes(['block'], node)
# for n in nameNodes:
# self.body = BlockNode(n)
for n in nameNodes:
self.body = BlockNode(n)
if self.body: self.children.append(self.body)
......
......@@ -112,6 +112,12 @@ def run(testFiles):
buildEnvAndLink(ASTs)
print("<<<<------- after buildEnvAndLink -------->>>>>>")
for (n, t) in ASTs:
print(n)
print("--------------------")
t.printTree()
print("\n \n\n \n")
print("Succeeded")
print("**********************************************************")
......
......@@ -61,6 +61,19 @@ class ClassNode(ASTNode):
self.env = env
return env
def linkType(self):
# link types to the actual nodes fom the environment (envs already created)
# to use: self.env.getNode(name, namespace)
# print('hello here we go we are in classNode {}'.format(self.name))
if self.env is not None:
if self.superClass is not '':
newSuperClass = self.env.getNode(self.superClass, 'type')
self.superClass = newSuperClass
if self.superInter is not []:
for (index, inter) in enumerate(self.superInter):
newSuperInter = self.env.getNode(inter, 'type')
self.superInter[index] = newSuperInter
def getConstructor(self, argTypes):
for c in self.constructors:
if c.paramTypes == argTypes:
......
......@@ -20,7 +20,7 @@ class LiteralNode(ASTNode):
# always list all fields in the init method to show the class structure
def __init__(self, parseTree):
self.parseTree = parseTree
self.liType = toLiType.get(parseTree.children[0].name) # type of the literal
self.liType = LiteralNode.toLiType.get(parseTree.children[0].name) # type of the literal
self.value = parseTree.children[0].lex # the value
self.env = None
self.children = []
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment