From 69a84e4c2f794be6ac86fe2516065a8ed8b743d8 Mon Sep 17 00:00:00 2001 From: Xun Yang <x299yang@uwaterloo.ca> Date: Fri, 6 Mar 2020 21:04:17 -0500 Subject: [PATCH] forward ref checks --- MemberNodes.py | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/MemberNodes.py b/MemberNodes.py index 4eeabd1..87caedc 100644 --- a/MemberNodes.py +++ b/MemberNodes.py @@ -37,6 +37,20 @@ class FieldNode(ASTNode): def checkType(self): self.variableDcl.checkType() + # check forward reference + if self.variableDcl.variableInit: + allNames = getForwardRefNames(self.variableDcl.variableInit) + from pprint import pprint + + for n in allNames: + if n.prefixLink is self.variableDcl: + raise Exception("ERROR: Forward reference of field {} in itself is not allowed.".format(n.prefixLink.name)) + + if n.prefixLink.__class__.__name__ == 'FieldNode' \ + and n.prefixLink.typeName == self.typeName \ + and self.order <= n.prefixLink.order \ + and "this" not in n.name: + raise Exception("ERROR: Forward reference of field {} is not allowed.".format(n.prefixLink.name)) ########################################################### @@ -106,6 +120,12 @@ class MethodNode(ASTNode): self.env = env return env + def disambigName(self): + if self.body: + self.body.disambigName() + for p in self.params: + p.disambigName() + def checkType(self): if self.methodType: # constructor would be None self.myType = self.methodType.myType @@ -118,7 +138,7 @@ class MethodNode(ASTNode): # No method body: do not check type as function isn't implemented if not self.body: return - + # With method body returnNodes = getASTNode(["ReturnNode"], self.body) @@ -127,7 +147,7 @@ class MethodNode(ASTNode): # Either a constructor or the function has type Void if not self.methodType or self.myType.name == "void": return - raise Exception("ERROR: no return statement at function {}".format(self.name)) + raise Exception("ERROR: no return statement at function {}".format(self.name)) # Checking for cases where there are return statements for n in returnNodes: @@ -135,9 +155,25 @@ class MethodNode(ASTNode): # Only valid if either the function doesn't have a return statement(checked above), or the return statement is a semicolon (return;) if self.myType.name == "void": if n.myType: - raise Exception("ERROR: return type of function {} doesn't match with return statement.".format(self.name)) + raise Exception("ERROR: return type of function {} doesn't match with return statement.".format(self.name)) # Checking for non void cases if not self.myType.assignable(n.myType): raise Exception("ERROR: return type of function {} doesn't match with return statement.".format(self.name)) - return \ No newline at end of file + return + +############# helper for forward ref checking ######## +# Input: AST Node +# Output: A list of names to be check +def getForwardRefNames(node): + if node.__class__.__name__ == 'NameNode': + return [node] + + result = [] + if node.__class__.__name__ == 'AssignNode': + result.extend(getForwardRefNames(node.right)) + else: + for c in node.children: + result.extend(getForwardRefNames(c)) + + return result -- GitLab