From d5a4bcd8e40597af85a31fe830760d1f0791e35d Mon Sep 17 00:00:00 2001 From: pycsham <shampuiyanchloe@gmail.com> Date: Fri, 6 Mar 2020 18:53:45 -0500 Subject: [PATCH] implemented method return type checking --- AST.py | 18 ++++++++++++++++++ LineNodes.py | 2 +- MemberNodes.py | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/AST.py b/AST.py index 7a67a49..885000e 100644 --- a/AST.py +++ b/AST.py @@ -108,3 +108,21 @@ def getParseTreeNodes(names, tree, terminateList = []): else: result.extend(getParseTreeNodes(names, n, terminateList)) return result + +def getASTNode(names, AST): + result = [] + if not AST: + return result + if AST.__class__.__name__ in names: + result.append(AST) + return result + if not AST.children: + return [] + for n in AST.children: + if not n: + continue + if n.__class__.__name__ in names: + result.append(n) + else: + result.extend(getASTNode(names, n)) + return result diff --git a/LineNodes.py b/LineNodes.py index 52f1a02..57d091e 100644 --- a/LineNodes.py +++ b/LineNodes.py @@ -209,7 +209,7 @@ class ReturnNode(ASTNode): self.expr.checkType() self.myType = self.expr.myType else: - self.myType = TypeStruct("void", None) + self.myType = None # this is None as returning a value of type Void is invalid even in a function with type Void # forStatement and forStatementNoShortIf # Rules: diff --git a/MemberNodes.py b/MemberNodes.py index 13ba951..4eeabd1 100644 --- a/MemberNodes.py +++ b/MemberNodes.py @@ -1,4 +1,4 @@ -from AST import ASTNode, getParseTreeNodes +from AST import ASTNode, getParseTreeNodes, getASTNode from LineNodes import BlockNode, VarDclNode from ExprPrimaryNodes import makeNodeFromExpr from UnitNodes import ParamNode @@ -107,9 +107,37 @@ class MethodNode(ASTNode): return env def checkType(self): - if self.methodType: # constructor + if self.methodType: # constructor would be None self.myType = self.methodType.myType for p in self.params: p.checkType() if self.body: self.body.checkType() + + # Checking return types against the function type + # 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) + + # Checking for cases where there are no return statements + if not returnNodes: + # 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)) + + # Checking for cases where there are return statements + for n in returnNodes: + # Checking for functions of type void + # 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)) + + # 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 -- GitLab