View difference between Paste ID: PGxd2rVd and z4zdvMd4
SHOW: | | - or go back to the newest paste.
1
    ##################### NAME IN OOP: QUESTION 2 ###########################
2
class GetEnv(Visitor): 
3
    def visitProgram(self,ctx:Program,o:object):
4
        o = []
5
        for decl in ctx.decl: 
6
             o = self.visit(decl,o)
7
        return o
8
    def visitClassDecl(self,ctx:ClassDecl,o:object):
9
        if ctx.name in o: 
10
            raise RedeclaredField(ctx.name) 
11
        env = []
12
        foundParent = False
13
        if len(ctx.parent) != 0: 
14
            for decl in o: 
15
                if len(decl) == 3: 
16
                    if ctx.parent == decl[0]:
17
                        env += decl[2]
18
                        foundParent = True
19
            if foundParent == False: raise UndeclaredClass(ctx.parent)
20
        for decl in ctx.mem: 
21
            env = self.visit(decl,env)
22
        o += [(ctx.name,ctx.parent,env)]
23
        return o    
24
    def visitVarDecl(self,ctx:VarDecl,o:object):
25
        if ctx.name in o: 
26
            raise RedeclaredField(ctx.name)
27
        o += [(ctx.name,ctx.typ)]
28
        return o
29
    def visitFuncDecl(self,ctx:FuncDecl,o:object):
30
        env = []
31
        if ctx.name in o: 
32
            raise RedeclaredMethod(ctx.name)
33
        o += [(ctx.name,None)]
34
        for decl in ctx.param: 
35
            env = self.visit(decl,env)
36
        for decl in ctx.body[0]: 
37
            env = self.visit(decl,env)
38
        return o
39
class StaticCheck(Visitor):
40
    def visitProgram(self,ctx:Program,o:object):
41
        env = GetEnv().visit(ctx,o)
42
        for decl in ctx.decl: 
43
            self.visit(decl,env)
44
    def visitClassDecl(self,ctx:ClassDecl,o:object):
45
        for decl in ctx.mem: 
46
            if type(decl) is FuncDecl: 
47
                self.visit(decl,o)
48
    def visitVarDecl(self,ctx:VarDecl,o:object):
49
        if ctx.name in o: 
50
            raise RedeclaredField(ctx.name)
51
        o += [(ctx.name,ctx.typ)]
52
    def visitFuncDecl(self,ctx:FuncDecl,o:object):
53
        env = ctx.param + ctx.body[0]
54
        NotDeclInFunction = o
55
        for expr in ctx.body[1]: 
56
            self.visit(expr,(env,NotDeclInFunction))
57
    def visitIntType(self,ctx:IntType,o:object):pass
58
 
59
    def visitFloatType(self,ctx:FloatType,o:object):pass
60
 
61
    def visitClassType(self,ctx:ClassType,o:object):pass
62
 
63
    def visitIntLit(self,ctx:IntLit,o:object):pass
64
 
65
    def visitId(self,ctx:Id,o:object):
66
        idTyp = None
67
        for element in o[0]: # o[0] is local scope of function  
68
            if ctx.name == element.name: # there is no class decl inside function LOL 
69
                idTyp = element.typ
70
        if not idTyp : # Two type of stuff inside function: FuncDecl and VarDecl
71
            raise UndeclaredIdentifier(ctx.name)
72
        return idTyp
73
    def visitFieldAccess(self,ctx:FieldAccess,o:object): 
74
        typ = self.visit(ctx.exp,o)
75
        if type(typ) is ClassType:
76
            classData = None
77
            for x in o[1]: # global scope
78
                if typ.name == x[0]:
79
                    classData = x
80
                    break
81
            if classData == None: raise UndeclaredClass(typ.name)
82
            for classElement in classData[2]:
83
                if ctx.field == classElement[0]:
84
                    return
85
            raise UndeclaredField(ctx.field)
86