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 |