raiseException("ERROR: assignment operation failed. Cannot assign type {0} to type {1} at class {2}".format(self.left.myType.name,self.right.myType.name,self.typeName))
raiseException("ERROR: assignment operation failed. Cannot assign type {0} to type {1} at class {2}".format(self.left.myType.name,self.right.myType.name,self.typeName))
defreachCheck(self,inMaybe):
defreachCheck(self,inMaybe):
ifnotinMaybe:
ifnotinMaybe:
raiseException("ERROR: not reaching a assignment statement")
raiseException("ERROR: not reaching a assignment statement")
self.cons=None# the constructor used to create the class
self.cons=None# the constructor used to create the class
defcheckType(self):
defcheckType(self):
# return # TO REMOVE after name node type checking is done
# return # TO REMOVE after name node type checking is done
self.args.checkType()
self.args.checkType()
classDef=self.className.myType.typePointer
classDef=self.className.myType.typePointer
# check class is not abstract
# check class is not abstract
if'abstract'inclassDef.mods:
if'abstract'inclassDef.mods:
raiseException('ERROR: Cannot create an instance of abstract class {}.'.format(self.className.myType.name))
raiseException('ERROR: Cannot create an instance of abstract class {}.'.format(self.className.myType.name))
elifclassDef.__class__.__name__!='ClassNode':
elifclassDef.__class__.__name__!='ClassNode':
raiseException('ERROR: Cannot create an instance of {}, it is not a class.'.format(self.className.myType.name))
raiseException('ERROR: Cannot create an instance of {}, it is not a class.'.format(self.className.myType.name))
# check 0 arguement constructor of superclass exists
# check 0 arguement constructor of superclass exists
su=classDef.superClass
su=classDef.superClass
whilesu!='':# if it doesn't have an explict super class, its super class is java.lang.object, which is safe
whilesu!='':# if it doesn't have an explict super class, its super class is java.lang.object, which is safe
found=False
found=False
forcinsu.constructors:
forcinsu.constructors:
ifc.params==[]:
ifc.params==[]:
found=True
found=True
break
break
ifnotfound:
ifnotfound:
raiseException("ERROR: Class {} doesn't have a zero-arguement constructor.".format(su.name))
raiseException("ERROR: Class {} doesn't have a zero-arguement constructor.".format(su.name))
su=su.superClass
su=su.superClass
# get constructor using arg Types
# get constructor using arg Types
m=getMethod(classDef.constructors,"",self.args)
m=getMethod(classDef.constructors,"",self.args)
ifm:
ifm:
self.cons=m
self.cons=m
self.myType=self.className.myType
self.myType=self.className.myType
else:
else:
raiseException("ERROR: Class {} doesn't have a constructor with given argument types.".format(classDef.name))
raiseException("ERROR: Class {} doesn't have a constructor with given argument types.".format(classDef.name))
# check to make sure we are allowed to call this (protected?)
# check to make sure we are allowed to call this (protected?)
# if self.cons is protected, check that:
# if self.cons is protected, check that:
# - current class is in the same package
# - current class is in the same package
if'protected'inself.cons.mods:
if'protected'inself.cons.mods:
curClass=self.env.getNode(self.typeName,'type')
curClass=self.env.getNode(self.typeName,'type')
ifcurClass.packageName!=classDef.packageName:
ifcurClass.packageName!=classDef.packageName:
raiseException("ERROR: In class {0}, using a protected constructor, but class {1} is not in class {0}'s package ({2}).".format(curClass.name,classDef.name,curClass.packageName))
raiseException("ERROR: In class {0}, using a protected constructor, but class {1} is not in class {0}'s package ({2}).".format(curClass.name,classDef.name,curClass.packageName))
raiseException("ERROR: Incompatible types. Left of {} type can't be used with right of {} type on operation {}".format(self.left.myType.name,self.right.myType.name,self.op))
raiseException("ERROR: Incompatible types. Left of {} type can't be used with right of {} type on operation {}".format(self.left.myType.name,self.right.myType.name,self.op))
# returns True, False, Int or None (for non-constant expr)
# returns True, False, Int or None (for non-constant expr)
# children of exprNode is either exprNode or literalNode
# children of exprNode is either exprNode or literalNode
methods.extend([methformethinself.primary.myType.typePointer.inheritsifisinstance(meth,MemberNodes.MethodNode)])# need to check inherited methods as well
methods.extend([methformethinself.primary.myType.typePointer.inheritsifisinstance(meth,MemberNodes.MethodNode)])# need to check inherited methods as well
m=getMethod(methods,self.ID.name,self.args)
m=getMethod(methods,self.ID.name,self.args)
ifm:
ifm:
# check static
# I don't see any need for this check, this check causes more harm than good
ifself.ID.shouldBeStaticand(not'static'inm.mods):
# because you can call System.out.println, where 'System' is a class with static field 'out',
raiseException("ERROR: Static access of non-static method {}.".format(m.name))
# which is of type 'PrintStream' which has non-static method 'println', thus going into this if statement
if (notself.ID.shouldBeStatic)and'static'inm.mods:
# if self.ID.shouldBeStatic and (not 'static' in m.mods):
raiseException("ERROR: Non-static access of static method {}.".format(m.name))
# raise Exception("ERROR: Static access of non-static method {}.".format(m.name))
# check protected
# check static
if"protected"inm.mods:
if (notself.ID.shouldBeStatic)and'static'inm.mods:
checkProtected(m,self)
raiseException("ERROR: Non-static access of static method {}.".format(m.name))
self.method=m
# check protected
self.myType=m.methodType.myType
if"protected"inm.mods:
return
checkProtected(m,self)
else:
self.method=m
raiseException("ERROR: Class {} doesn't have a method {} with given argument types.".format(self.typeName,self.ID.name))
self.myType=m.methodType.myType
return
defreachCheck(self,inMaybe):
else:
ifnotinMaybe:
raiseException("ERROR: not reaching a variable declaration statement for var {}".format(self.name))
raiseException("ERROR: Class {} doesn't have a method {} with given argument types.".format(self.typeName,self.ID.name))
self.outMaybe=inMaybe
defreachCheck(self,inMaybe):
################# Helper #######################
ifnotinMaybe:
raiseException("ERROR: not reaching a variable declaration statement for var {}".format(self.name))
defgetMethod(methods,methodName,args):
self.outMaybe=inMaybe
# methodName = "" if it's constructor
forcinmethods:
################# Helper #######################
if (methodName==""orc.name==methodName)andlen(args.exprs)==len(c.params):
found=True
defgetMethod(methods,methodName,args):
fori,paraminenumerate(args.exprs):
# methodName = "" if it's constructor
ifc.params[i].paramType.myType!=param.myType:
forcinmethods:
found=False
if (methodName==""orc.name==methodName)andlen(args.exprs)==len(c.params):