Mercurial > lcfOS
annotate python/c3/analyse.py @ 226:240111e0456f
Work on named types
author | Windel Bouwman |
---|---|
date | Fri, 12 Jul 2013 17:25:31 +0200 |
parents | 1c7364bd74c7 |
children | 82dfe6a32717 |
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 |
226 | 81 elif type(t) is StructureType: |
82 for mem in t.mems: | |
83 mem.typ = self.resolveType(mem.typ, scope) | |
84 return t | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
85 elif type(t) is Designator: |
226 | 86 t = self.resolveDesignator(t, scope) |
87 return self.resolveType(t) | |
225 | 88 elif isinstance(t, Type): |
89 # Already resolved?? | |
90 return t | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
91 else: |
225 | 92 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
|
93 |
215 | 94 def findRefs(self, sym): |
95 if type(sym) in [Variable, Constant]: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
96 sym.typ = self.resolveType(sym.typ, sym.scope) |
222 | 97 elif type(sym) is TypeCast: |
98 sym.to_type = self.resolveType(sym.to_type, sym.scope) | |
215 | 99 elif type(sym) is VariableUse: |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
100 sym.target = self.resolveDesignator(sym.target, sym.scope) |
215 | 101 elif type(sym) is FunctionCall: |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
102 varuse = sym.proc |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
103 sym.proc = self.resolveDesignator(varuse.target, sym.scope) |
215 | 104 elif type(sym) is Function: |
105 # Checkup function type: | |
106 ft = sym.typ | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
107 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
|
108 ft.parametertypes = [self.resolveType(pt, sym.scope) for pt in ft.parametertypes] |
226 | 109 elif type(sym) is DefinedType: |
110 sym.typ = self.resolveType(sym.typ, sym.scope) | |
215 | 111 |
112 def sanity(self, sym): | |
113 if type(sym) is FunctionType: | |
114 pass | |
115 elif type(sym) is Function: | |
116 pass | |
117 |