Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ##################### NAME IN OOP: QUESTION 2 ###########################
- class GetEnv(Visitor):
- def visitProgram(self,ctx:Program,o:object):
- o = []
- for decl in ctx.decl:
- o = self.visit(decl,o)
- return o
- def visitClassDecl(self,ctx:ClassDecl,o:object):
- if ctx.name in o:
- raise RedeclaredField(ctx.name)
- env = []
- foundParent = False
- if len(ctx.parent) != 0:
- for decl in o:
- if len(decl) == 3:
- if ctx.parent == decl[0]:
- env += decl[2]
- foundParent = True
- if foundParent == False: raise UndeclaredClass(ctx.parent)
- for decl in ctx.mem:
- env = self.visit(decl,env)
- o += [(ctx.name,ctx.parent,env)]
- return o
- def visitVarDecl(self,ctx:VarDecl,o:object):
- if ctx.name in o:
- raise RedeclaredField(ctx.name)
- o += [(ctx.name,ctx.typ)]
- return o
- def visitFuncDecl(self,ctx:FuncDecl,o:object):
- env = []
- if ctx.name in o:
- raise RedeclaredMethod(ctx.name)
- o += [(ctx.name,None)]
- for decl in ctx.param:
- env = self.visit(decl,env)
- for decl in ctx.body[0]:
- env = self.visit(decl,env)
- return o
- class StaticCheck(Visitor):
- def visitProgram(self,ctx:Program,o:object):
- env = GetEnv().visit(ctx,o)
- for decl in ctx.decl:
- self.visit(decl,env)
- def visitClassDecl(self,ctx:ClassDecl,o:object):
- for decl in ctx.mem:
- if type(decl) is FuncDecl:
- self.visit(decl,o)
- def visitVarDecl(self,ctx:VarDecl,o:object):
- if ctx.name in o:
- raise RedeclaredField(ctx.name)
- o += [(ctx.name,ctx.typ)]
- def visitFuncDecl(self,ctx:FuncDecl,o:object):
- env = ctx.param + ctx.body[0]
- NotDeclInFunction = o
- for expr in ctx.body[1]:
- self.visit(expr,(env,NotDeclInFunction))
- def visitIntType(self,ctx:IntType,o:object):pass
- def visitFloatType(self,ctx:FloatType,o:object):pass
- def visitClassType(self,ctx:ClassType,o:object):pass
- def visitIntLit(self,ctx:IntLit,o:object):pass
- def visitId(self,ctx:Id,o:object):
- idTyp = None
- for element in o[0]: # o[0] is local scope of function
- if ctx.name == element.name: # there is no class decl inside function LOL
- idTyp = element.typ
- if not idTyp : # Two type of stuff inside function: FuncDecl and VarDecl
- raise UndeclaredIdentifier(ctx.name)
- return idTyp
- def visitFieldAccess(self,ctx:FieldAccess,o:object):
- typ = self.visit(ctx.exp,o)
- if type(typ) is ClassType:
- classData = None
- for x in o[1]: # global scope
- if typ.name == x[0]:
- classData = x
- break
- if classData == None: raise UndeclaredClass(typ.name)
- for classElement in classData[2]:
- if ctx.field == classElement[0]:
- return
- raise UndeclaredField(ctx.field)
Add Comment
Please, Sign In to add comment