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

implemented method return type checking

parent af6723ea
No related branches found
No related tags found
No related merge requests found
...@@ -108,3 +108,21 @@ def getParseTreeNodes(names, tree, terminateList = []): ...@@ -108,3 +108,21 @@ def getParseTreeNodes(names, tree, terminateList = []):
else: else:
result.extend(getParseTreeNodes(names, n, terminateList)) result.extend(getParseTreeNodes(names, n, terminateList))
return result 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
...@@ -209,7 +209,7 @@ class ReturnNode(ASTNode): ...@@ -209,7 +209,7 @@ class ReturnNode(ASTNode):
self.expr.checkType() self.expr.checkType()
self.myType = self.expr.myType self.myType = self.expr.myType
else: 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 # forStatement and forStatementNoShortIf
# Rules: # Rules:
......
from AST import ASTNode, getParseTreeNodes from AST import ASTNode, getParseTreeNodes, getASTNode
from LineNodes import BlockNode, VarDclNode from LineNodes import BlockNode, VarDclNode
from ExprPrimaryNodes import makeNodeFromExpr from ExprPrimaryNodes import makeNodeFromExpr
from UnitNodes import ParamNode from UnitNodes import ParamNode
...@@ -107,9 +107,37 @@ class MethodNode(ASTNode): ...@@ -107,9 +107,37 @@ class MethodNode(ASTNode):
return env return env
def checkType(self): def checkType(self):
if self.methodType: # constructor if self.methodType: # constructor would be None
self.myType = self.methodType.myType self.myType = self.methodType.myType
for p in self.params: for p in self.params:
p.checkType() p.checkType()
if self.body: if self.body:
self.body.checkType() 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
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