163
|
1 from .visitor import Visitor
|
|
2 from .astnodes import *
|
150
|
3
|
|
4 class Analyzer:
|
163
|
5 """ This class checks names and references """
|
150
|
6 def __init__(self, diag):
|
|
7 self.diag = diag
|
163
|
8 self.visitor = Visitor(self.a1, self.analyze)
|
186
|
9
|
163
|
10 def analyzePackage(self, pkg):
|
186
|
11 self.ok = True
|
|
12 self.visitor.visit(pkg)
|
|
13 return self.ok
|
163
|
14 def resolveDesignator(self, d, referee=None):
|
|
15 assert type(d) is Designator
|
|
16 if d.scope.hasSymbol(d.tname):
|
|
17 s = d.scope.getSymbol(d.tname)
|
|
18 if hasattr(s, 'addRef'):
|
|
19 # TODO: make this nicer
|
|
20 s.addRef(referee)
|
|
21 return s
|
|
22 else:
|
186
|
23 self.ok = False
|
163
|
24 msg = 'Cannot resolve name {0}'.format(d.tname)
|
|
25 self.diag.error(msg, d.loc)
|
|
26 def a1(self, sym):
|
|
27 pass
|
|
28 def analyze(self, sym):
|
166
|
29 if type(sym) in [Variable, Constant]:
|
163
|
30 sym.typ = self.resolveDesignator(sym.typ, sym)
|
167
|
31 elif type(sym) is Function:
|
|
32 pass
|
163
|
33 elif type(sym) is VariableUse:
|
|
34 sym.target = self.resolveDesignator(sym.target, sym)
|
167
|
35 elif type(sym) is FunctionCall:
|
163
|
36 sym.proc = self.resolveDesignator(sym.proc, sym)
|
|
37 elif type(sym) is FunctionType:
|
|
38 sym.returntype = self.resolveDesignator(sym.returntype)
|
167
|
39 sym.parametertypes = [self.resolveDesignator(pt) for pt in sym.parametertypes]
|
150
|
40
|