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

implemented environment building and double local variable checking

parent 1cce4cc5
No related branches found
No related tags found
1 merge request!4Chloe environment building
......@@ -11,6 +11,7 @@ class ASTNode():
# but we will keep it for easier debugging, since effeciency is not a concern here
def __init__(self, parseTree):
self.parseTree = parseTree
self.children = []
# Do certains actions on every node of the AST tree
# call the same method in each class and its children recursively
......@@ -27,6 +28,21 @@ class ASTNode():
if hasattr(c, 'recurseAction'):
c.recurseAction(actionName, result)
# This is a function to recursively build environment
# Modified from the function recurseAction above, to handle the proper linking of local variable environments
def recurseBuildEnv(self, parentEnv):
result = self.buildEnv(parentEnv)
preVarDcl = None
for c in self.children:
if c and hasattr(c, 'recurseBuildEnv'):
if preVarDcl:
c.recurseBuildEnv(preVarDcl.env)
else:
c.recurseBuildEnv(result)
if c.__class__.__name__ == 'VarDclNode':
preVarDcl = c
def buildEnv(self, parentEnv):
self.env = parentEnv
return parentEnv
......
......@@ -9,6 +9,8 @@ def astBuild(trees):
ASTs.append((n, CompNode(t)))
return ASTs
def buildEnvAndLink(ASTs):
# build env
globalEnv = GlobalEnv()
......@@ -19,10 +21,13 @@ def buildEnvAndLink(ASTs):
pprint(vars(globalEnv))
for t in ASTs:
t[1].recurseAction("buildEnv", globalEnv)
try:
t[1].recurseBuildEnv(globalEnv)
except Exception as e: # to handle double local variable declaration
print('\n\n\n', t[0])
print("###################### Comp Unit Env ####################")
t[1].recurseAction("printEnv")
# type Linking
print('--------->>> type linking time!')
......
......@@ -2,10 +2,12 @@ import string
class Env:
nodeToNamespace = dict({
'FieldNode': 'expr',
'FieldNode': 'fieldDcl',
'InterNode': 'type',
'ClassNode': 'type',
'MethodNode': 'method'
'MethodNode': 'method',
'VarDclNode': 'expr'
})
def __init__(self, parentEnv):
......@@ -49,6 +51,16 @@ class Env:
return self.parentEnv.getNode(name, namespace)
raise Exception("ERROR: Can't find definition of {} in the Environment".format(name))
# A wrapper around getNode to find if node exists in environment already
def findNode(self, name, namespace):
try:
self.getNode(name, namespace)
except:
return False # node is not found in environment
return True
###################################
class GlobalEnv(Env):
......
......@@ -80,12 +80,12 @@ class BlockNode(ASTNode):
self.children = self.statements
# def buildEnv(self, parentEnv):
def buildEnv(self, parentEnv):
env = Env(parentEnv)
self.env = env
return self.env
# variableDcl
# Rules:
# 1. variableDcl type ID
......@@ -94,23 +94,30 @@ class VarDclNode(ASTNode):
def __init__(self, parseTree):
self.parseTree = parseTree
self.dclType = None
self.varName = None
self.name = None # variable name
self.variableInit = None # could be none if not intialized
self.env = None
self.children = []
self.dclType = TypeNode(parseTree.children[0])
self.varName = parseTree.children[1].lex
self.name = parseTree.children[1].lex
if len(parseTree.children) > 2:
# Handling rule: variableInit expr
self.variableInit = makeNodeFromExpr(parseTree.children[3].children[0])
self.children.append(self.dclType)
self.children.append(self.varName)
self.children.append(self.variableInit)
def buildEnv(self, parentEnv):
env = Env(parentEnv)
self.env = env
# check if the node already exists in environment
if parentEnv.findNode(self.name, 'expr'):
raise Exception("ERROR: Double Local Variable Declaration {}".format(self.name))
else:
env.addtoEnv(self)
return self.env
# ifStatement, ifElseStatement, ifElseStatementNoShortIf
# Rules:
......@@ -145,7 +152,7 @@ class WhileNode(ASTNode):
self.env = None
self.children = []
self.whileBound = None
self.whileBody = None
self.whileBody = None
self.whileBound = makeNodeFromExpr(parseTree.children[2])
self.whileBody = makeNodeFromAllStatement(parseTree.children[4])
......
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