Mercurial > lcfOS
annotate python/c3/analyse.py @ 225:1c7364bd74c7
Fixed pointer deref
author | Windel Bouwman |
---|---|
date | Thu, 11 Jul 2013 07:42:30 +0200 |
parents | c3f1ce8b638f |
children | 240111e0456f |
rev | line source |
---|---|
163 | 1 from .visitor import Visitor |
2 from .astnodes import * | |
215 | 3 from .scope import Scope, topScope |
150 | 4 |
5 class Analyzer: | |
215 | 6 """ |
7 Context handling is done here. | |
8 Scope is attached to the correct modules. | |
9 This class checks names and references | |
10 """ | |
11 def __init__(self, diag): | |
12 self.diag = diag | |
186 | 13 |
215 | 14 def analyzePackage(self, pkg): |
186 | 15 self.ok = True |
215 | 16 visitor = Visitor() |
17 # Prepare top level scope: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
18 self.scopeStack = [topScope] |
215 | 19 visitor.visit(pkg, self.enterScope, self.quitScope) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
20 del self.scopeStack |
215 | 21 visitor.visit(pkg, self.findRefs) |
22 visitor.visit(pkg, self.sanity) | |
186 | 23 return self.ok |
215 | 24 |
25 def error(self, msg, loc=None): | |
26 self.ok = False | |
27 self.diag.error(msg, loc) | |
28 | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
29 @property |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
30 def currentScope(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
31 return self.scopeStack[-1] |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
32 |
215 | 33 # Scope creation: |
34 def addSymbol(self, sym): | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
35 if self.currentScope.hasSymbol(sym.name): |
215 | 36 self.error('Redefinition of {0}'.format(sym.name), sym.loc) |
37 else: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
38 self.currentScope.addSymbol(sym) |
215 | 39 |
40 def enterScope(self, sym): | |
41 # Distribute the scope: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
42 sym.scope = self.currentScope |
215 | 43 |
44 # Add symbols to current scope: | |
45 if isinstance(sym, Symbol): | |
46 self.addSymbol(sym) | |
225 | 47 if isinstance(sym, DefinedType): |
48 self.addSymbol(sym) | |
215 | 49 |
50 # Create subscope: | |
51 if type(sym) in [Package, Function]: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
52 newScope = Scope(self.currentScope) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
53 self.scopeStack.append(newScope) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
54 sym.innerScope = self.currentScope |
215 | 55 |
56 def quitScope(self, sym): | |
57 # Pop out of scope: | |
58 if type(sym) in [Package, Function]: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
59 self.scopeStack.pop(-1) |
150 | 60 |
215 | 61 # Reference fixups: |
62 def resolveDesignator(self, d, scope): | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
63 assert type(d) is Designator, type(d) |
215 | 64 assert type(scope) is Scope |
65 if scope.hasSymbol(d.tname): | |
66 s = scope.getSymbol(d.tname) | |
67 if hasattr(s, 'addRef'): | |
68 # TODO: make this nicer | |
69 s.addRef(None) | |
70 return s | |
71 else: | |
72 self.ok = False | |
73 msg = 'Cannot resolve name {0}'.format(d.tname) | |
74 self.diag.error(msg, d.loc) | |
75 | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
76 def resolveType(self, t, scope): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
77 # TODO: what about structs? |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
78 if type(t) is PointerType: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
79 t.ptype = self.resolveType(t.ptype, scope) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
80 return t |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
81 elif type(t) is Designator: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
82 return self.resolveDesignator(t, scope) |
225 | 83 elif isinstance(t, Type): |
84 # Already resolved?? | |
85 return t | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
86 else: |
225 | 87 raise Exception('Error resolving type {} {}'.format(t, type(t))) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
88 |
215 | 89 def findRefs(self, sym): |
90 if type(sym) in [Variable, Constant]: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
91 sym.typ = self.resolveType(sym.typ, sym.scope) |
222 | 92 elif type(sym) is TypeCast: |
93 sym.to_type = self.resolveType(sym.to_type, sym.scope) | |
215 | 94 elif type(sym) is VariableUse: |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
95 sym.target = self.resolveDesignator(sym.target, sym.scope) |
215 | 96 elif type(sym) is FunctionCall: |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
97 varuse = sym.proc |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
98 sym.proc = self.resolveDesignator(varuse.target, sym.scope) |
215 | 99 elif type(sym) is Function: |
100 # Checkup function type: | |
101 ft = sym.typ | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
102 ft.returntype = self.resolveType(ft.returntype, sym.scope) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
103 ft.parametertypes = [self.resolveType(pt, sym.scope) for pt in ft.parametertypes] |
215 | 104 |
105 def sanity(self, sym): | |
106 if type(sym) is FunctionType: | |
107 pass | |
108 elif type(sym) is Function: | |
109 pass | |
110 |