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