Mercurial > lcfOS
comparison python/c3/analyse.py @ 215:c1ccb1cb4cef
Major changes in c3 frontend
author | Windel Bouwman |
---|---|
date | Fri, 05 Jul 2013 13:00:03 +0200 |
parents | 46d62dadd61b |
children | 8b2e5f3cd579 |
comparison
equal
deleted
inserted
replaced
214:6875360e8390 | 215:c1ccb1cb4cef |
---|---|
1 from .visitor import Visitor | 1 from .visitor import Visitor |
2 from .astnodes import * | 2 from .astnodes import * |
3 from .scope import Scope, topScope | |
3 | 4 |
4 class Analyzer: | 5 class Analyzer: |
5 """ This class checks names and references """ | 6 """ |
6 def __init__(self, diag): | 7 Context handling is done here. |
7 self.diag = diag | 8 Scope is attached to the correct modules. |
8 self.visitor = Visitor(self.a1, self.analyze) | 9 This class checks names and references |
10 """ | |
11 def __init__(self, diag): | |
12 self.diag = diag | |
9 | 13 |
10 def analyzePackage(self, pkg): | 14 def analyzePackage(self, pkg): |
11 self.ok = True | 15 self.ok = True |
12 self.visitor.visit(pkg) | 16 visitor = Visitor() |
17 # Prepare top level scope: | |
18 self.curScope = topScope | |
19 visitor.visit(pkg, self.enterScope, self.quitScope) | |
20 del self.curScope | |
21 visitor.visit(pkg, self.findRefs) | |
22 visitor.visit(pkg, self.sanity) | |
13 return self.ok | 23 return self.ok |
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: | |
23 self.ok = False | |
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): | |
29 if type(sym) in [Variable, Constant]: | |
30 sym.typ = self.resolveDesignator(sym.typ, sym) | |
31 elif type(sym) is Function: | |
32 pass | |
33 elif type(sym) is VariableUse: | |
34 sym.target = self.resolveDesignator(sym.target, sym) | |
35 elif type(sym) is FunctionCall: | |
36 sym.proc = self.resolveDesignator(sym.proc, sym) | |
37 elif type(sym) is FunctionType: | |
38 sym.returntype = self.resolveDesignator(sym.returntype) | |
39 sym.parametertypes = [self.resolveDesignator(pt) for pt in sym.parametertypes] | |
40 | 24 |
25 def error(self, msg, loc=None): | |
26 self.ok = False | |
27 self.diag.error(msg, loc) | |
28 | |
29 # Scope creation: | |
30 def addSymbol(self, sym): | |
31 if self.curScope.hasSymbol(sym.name): | |
32 self.error('Redefinition of {0}'.format(sym.name), sym.loc) | |
33 else: | |
34 self.curScope.addSymbol(sym) | |
35 | |
36 def enterScope(self, sym): | |
37 # Distribute the scope: | |
38 sym.scope = self.curScope | |
39 | |
40 # Add symbols to current scope: | |
41 if isinstance(sym, Symbol): | |
42 self.addSymbol(sym) | |
43 | |
44 # Create subscope: | |
45 if type(sym) in [Package, Function]: | |
46 self.curScope = Scope(self.curScope) | |
47 | |
48 def quitScope(self, sym): | |
49 # Pop out of scope: | |
50 if type(sym) in [Package, Function]: | |
51 self.curScope = self.curScope.parent | |
52 | |
53 # Reference fixups: | |
54 def resolveDesignator(self, d, scope): | |
55 assert type(d) is Designator | |
56 assert type(scope) is Scope | |
57 if scope.hasSymbol(d.tname): | |
58 s = scope.getSymbol(d.tname) | |
59 if hasattr(s, 'addRef'): | |
60 # TODO: make this nicer | |
61 s.addRef(None) | |
62 return s | |
63 else: | |
64 self.ok = False | |
65 msg = 'Cannot resolve name {0}'.format(d.tname) | |
66 self.diag.error(msg, d.loc) | |
67 | |
68 def findRefs(self, sym): | |
69 if type(sym) in [Variable, Constant]: | |
70 sym.typ = self.resolveDesignator(sym.typ, sym.scope) | |
71 elif type(sym) is VariableUse: | |
72 sym.target = self.resolveDesignator(sym.target, sym.scope) | |
73 elif type(sym) is FunctionCall: | |
74 sym.proc = self.resolveDesignator(sym.proc, sym.scope) | |
75 elif type(sym) is Function: | |
76 # Checkup function type: | |
77 ft = sym.typ | |
78 ft.returntype = self.resolveDesignator(ft.returntype, sym.scope) | |
79 ft.parametertypes = [self.resolveDesignator(pt, sym.scope) for pt in ft.parametertypes] | |
80 | |
81 def sanity(self, sym): | |
82 if type(sym) is FunctionType: | |
83 pass | |
84 elif type(sym) is Function: | |
85 pass | |
86 |