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