Skip to content
Snippets Groups Projects
Commit 23bede0d authored by Xun Yang's avatar Xun Yang
Browse files

type checking class create;

parent 10583e08
No related branches found
No related tags found
No related merge requests found
...@@ -227,13 +227,37 @@ class ClassCreateNode(ASTNode): ...@@ -227,13 +227,37 @@ class ClassCreateNode(ASTNode):
self.env = None self.env = None
self.children = [self.args, self.className] self.children = [self.args, self.className]
self.typeName = typeName self.typeName = typeName
self.cons = None # the constructor used to create the class
def checkType(self): def checkType(self):
return # TO REMOVE after name node type checking is done
classDef = self.className.myType.typePointer
# check class is not abstract # check class is not abstract
if 'abstract' in self.className.myType.typePointer.mods: if 'abstract' in classDef.mods:
raise Exception('ERROR: Cannot create an instance of abstract class {}.'.format(self.className.myType.name)) raise Exception('ERROR: Cannot create an instance of abstract class {}.'.format(self.className.myType.name))
# TODO: more type checking elif classDef.__class__.__name__ != 'ClassNode':
raise Exception('ERROR: Cannot create an instance of {}, it is not a class.'.format(self.className.myType.name))
# check 0 arguement constructor of superclass exists
su = classDef.superClass
while su != '': # if it doesn't have an explict super class, its super class is java.lang.object, which is safe
found = False
for c in su.constructors:
if c.params == []:
found = True
break
if not found:
raise Exception("ERROR: Class {} doesn't have a zero-arguement constructor.".format(su.name))
su = su.superClass
# get constructor using arg Types
found = False
m = getMethod(classDef.constructors, self.args)
if m:
self.cons = c
self.myType = self.className.myType
else:
raise Exception("ERROR: Class {} doesn't have a constructor with given argument types.".format(classDef.name))
################################################################################# #################################################################################
...@@ -277,43 +301,43 @@ class ExprNode(ASTNode): ...@@ -277,43 +301,43 @@ class ExprNode(ASTNode):
# Unary operations: # Unary operations:
if not self.left: if not self.left:
if self.op == '-' and self.right.myType.isNum(): if self.op == '-' and self.right.myType.isNum():
self.myType = TypeStruct("int") self.myType = TypeStruct("int", None)
return return
elif self.op == '!' and self.right.myType.name == 'boolean': elif self.op == '!' and self.right.myType.name == 'boolean':
self.myType = self.myType = TypeStruct("boolean") self.myType = self.myType = TypeStruct("boolean", None)
return return
# Numeric types # Numeric types
elif self.left.myType.isNum() and self.right.myType.isNum(): elif self.left.myType.isNum() and self.right.myType.isNum():
# Comparisons: # Comparisons:
if self.op in ['==', '!=', '<=', '>=', '>', '<']: if self.op in ['==', '!=', '<=', '>=', '>', '<']:
self.myType = TypeStruct("boolean") self.myType = TypeStruct("boolean", None)
return return
# numeric operations: # numeric operations:
elif self.op in ['+', '-', '*', '/']: elif self.op in ['+', '-', '*', '/']:
self.myType = TypeStruct("int") self.myType = TypeStruct("int", None)
return return
# Boolean operations: # Boolean operations:
elif self.left.myType.name == 'boolean' and self.right.myType.name == 'boolean': elif self.left.myType.name == 'boolean' and self.right.myType.name == 'boolean':
if self.op in ['&&', '&', '|', '||']: if self.op in ['&&', '&', '|', '||']:
self.myType = TypeStruct("boolean") self.myType = TypeStruct("boolean", None)
return return
# Other Comparisons: # Other Comparisons:
elif self.left.myType.assignable(self.right.myType) or self.right.myType.assignable(self.left.myType): elif self.left.myType.assignable(self.right.myType) or self.right.myType.assignable(self.left.myType):
if self.op == '==' or self.op == '!=': if self.op == '==' or self.op == '!=':
self.myType = TypeStruct("boolean") self.myType = TypeStruct("boolean", None)
return return
# String concat: # String concat:
elif (self.left.myType.name =='java.lang.String' and self.right.myType.name not in ['null', 'void']) \ elif (self.left.myType.name =='java.lang.String' and self.right.myType.name not in ['null', 'void']) \
or (self.right.myType.name =='java.lang.String' and self.left.myType.name not in ['null', 'void']): or (self.right.myType.name =='java.lang.String' and self.left.myType.name not in ['null', 'void']):
self.myType = TypeStruct('java.lang.String') self.myType = TypeStruct('java.lang.String', self.env.getNode('java.lang.String', 'type'))
self.myType.link(self.env) self.myType.link(self.env)
return return
elif self.op == 'instanceof': elif self.op == 'instanceof':
# assume it's correct for now, wait for runtime check # assume it's correct for now, wait for runtime check
self.myType = TypeStruct("boolean") self.myType = TypeStruct("boolean", None)
return return
raise Exception("ERROR: Incompatible types. Left of {} type can't be used with right of {} type on operation {}".format(self.op, self.left.myType.name, self.right.myType.name)) raise Exception("ERROR: Incompatible types. Left of {} type can't be used with right of {} type on operation {}".format(self.op, self.left.myType.name, self.right.myType.name))
...@@ -393,3 +417,16 @@ class MethodInvNode(ASTNode): ...@@ -393,3 +417,16 @@ class MethodInvNode(ASTNode):
if m.params[i].paramType != param.paramType: if m.params[i].paramType != param.paramType:
found = False found = False
found = True found = True
################# Helper #######################
def getMethod(methods, args):
for c in methods:
if len(args.exprs) == len(c.params):
found = True
for i, param in enumerate(args.exprs):
if c.params[i].paramType.myType != param.myType:
found = False
break
if found:
return c
return None
...@@ -14,15 +14,15 @@ class TypeNode(ASTNode): ...@@ -14,15 +14,15 @@ class TypeNode(ASTNode):
self.env = None self.env = None
self.children = [] self.children = []
self.myType = "" # empty string or typeStruct self.myType = "" # empty string or typeStruct
if parseTree == 'VOID': if parseTree == 'VOID':
self.myType = TypeStruct('void') self.myType = TypeStruct('void', None)
else: else:
nameNodes = getParseTreeNodes(['BOOLEAN', 'BYTE', 'CHAR', 'INT', 'SHORT'], parseTree) nameNodes = getParseTreeNodes(['BOOLEAN', 'BYTE', 'CHAR', 'INT', 'SHORT'], parseTree)
if nameNodes: if nameNodes:
self.myType = TypeStruct(nameNodes[0].lex) self.myType = TypeStruct(nameNodes[0].lex, None)
else: else:
self.myType = TypeStruct(getParseTreeNodes(['ID', 'COMPID'], parseTree)[0].lex) self.myType = TypeStruct(getParseTreeNodes(['ID', 'COMPID'], parseTree)[0].lex, None)
nameNodes = getParseTreeNodes(['LSQRBRACK'], parseTree) nameNodes = getParseTreeNodes(['LSQRBRACK'], parseTree)
if nameNodes: if nameNodes:
...@@ -36,10 +36,10 @@ class TypeNode(ASTNode): ...@@ -36,10 +36,10 @@ class TypeNode(ASTNode):
class TypeStruct(): class TypeStruct():
def __init__(self, name): def __init__(self, name, typePointer):
self.isArray = False self.isArray = False
self.isPrimitive = False self.isPrimitive = False
self.typePointer = None self.typePointer = typePointer
self.name = name self.name = name
if name in ['boolean', 'byte', 'char', 'int', 'short', 'void']: if name in ['boolean', 'byte', 'char', 'int', 'short', 'void']:
self.isPrimitive = True self.isPrimitive = True
......
...@@ -22,7 +22,7 @@ class LiteralNode(ASTNode): ...@@ -22,7 +22,7 @@ class LiteralNode(ASTNode):
self.parseTree = parseTree self.parseTree = parseTree
self.name = LiteralNode.toLiType.get(parseTree.children[0].name) # type of the literal self.name = LiteralNode.toLiType.get(parseTree.children[0].name) # type of the literal
self.value = parseTree.children[0].lex # the value self.value = parseTree.children[0].lex # the value
self.myType = TypeStruct(self.name) self.myType = TypeStruct(self.name, None)
self.env = None self.env = None
self.children = [] self.children = []
self.typeName = typeName self.typeName = typeName
......
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