Mercurial > lcfOS
annotate python/c3/analyse.py @ 231:521567d17388
simplify blink.c3
author | Windel Bouwman |
---|---|
date | Sat, 13 Jul 2013 20:20:44 +0200 |
parents | 82dfe6a32717 |
children | e41e4109addd |
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 |
215 | 15 def analyzePackage(self, pkg): |
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] |
215 | 20 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
|
21 del self.scopeStack |
215 | 22 visitor.visit(pkg, self.findRefs) |
23 visitor.visit(pkg, self.sanity) | |
186 | 24 return self.ok |
215 | 25 |
26 def error(self, msg, loc=None): | |
27 self.ok = False | |
28 self.diag.error(msg, loc) | |
29 | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
30 @property |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
31 def currentScope(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
32 return self.scopeStack[-1] |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
33 |
215 | 34 # Scope creation: |
35 def addSymbol(self, sym): | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
36 if self.currentScope.hasSymbol(sym.name): |
215 | 37 self.error('Redefinition of {0}'.format(sym.name), sym.loc) |
38 else: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
39 self.currentScope.addSymbol(sym) |
215 | 40 |
41 def enterScope(self, sym): | |
42 # Distribute the scope: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
43 sym.scope = self.currentScope |
215 | 44 |
45 # Add symbols to current scope: | |
46 if isinstance(sym, Symbol): | |
47 self.addSymbol(sym) | |
225 | 48 if isinstance(sym, DefinedType): |
49 self.addSymbol(sym) | |
215 | 50 |
51 # Create subscope: | |
52 if type(sym) in [Package, Function]: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
53 newScope = Scope(self.currentScope) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
54 self.scopeStack.append(newScope) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
55 sym.innerScope = self.currentScope |
215 | 56 |
57 def quitScope(self, sym): | |
58 # Pop out of scope: | |
59 if type(sym) in [Package, Function]: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
60 self.scopeStack.pop(-1) |
150 | 61 |
215 | 62 # Reference fixups: |
63 def resolveDesignator(self, d, scope): | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
64 assert type(d) is Designator, type(d) |
215 | 65 assert type(scope) is Scope |
66 if scope.hasSymbol(d.tname): | |
67 s = scope.getSymbol(d.tname) | |
68 if hasattr(s, 'addRef'): | |
69 # TODO: make this nicer | |
70 s.addRef(None) | |
71 return s | |
72 else: | |
73 self.ok = False | |
74 msg = 'Cannot resolve name {0}'.format(d.tname) | |
75 self.diag.error(msg, d.loc) | |
76 | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
77 def resolveType(self, t, scope): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
78 # TODO: what about structs? |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
79 if type(t) is PointerType: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
80 t.ptype = self.resolveType(t.ptype, scope) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
81 return t |
226 | 82 elif type(t) is StructureType: |
231 | 83 offset = 0 |
226 | 84 for mem in t.mems: |
231 | 85 mem.offset = offset |
226 | 86 mem.typ = self.resolveType(mem.typ, scope) |
231 | 87 offset += theType(mem.typ).bytesize |
88 t.bytesize = offset | |
226 | 89 return t |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
90 elif type(t) is Designator: |
226 | 91 t = self.resolveDesignator(t, scope) |
227 | 92 return self.resolveType(t, scope) |
225 | 93 elif isinstance(t, Type): |
94 # Already resolved?? | |
95 return t | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
96 else: |
225 | 97 raise Exception('Error resolving type {} {}'.format(t, type(t))) |
231 | 98 |
215 | 99 def findRefs(self, sym): |
100 if type(sym) in [Variable, Constant]: | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
101 sym.typ = self.resolveType(sym.typ, sym.scope) |
222 | 102 elif type(sym) is TypeCast: |
103 sym.to_type = self.resolveType(sym.to_type, sym.scope) | |
215 | 104 elif type(sym) is VariableUse: |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
105 sym.target = self.resolveDesignator(sym.target, sym.scope) |
215 | 106 elif type(sym) is FunctionCall: |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
107 varuse = sym.proc |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
108 sym.proc = self.resolveDesignator(varuse.target, sym.scope) |
215 | 109 elif type(sym) is Function: |
110 # Checkup function type: | |
111 ft = sym.typ | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
217
diff
changeset
|
112 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
|
113 ft.parametertypes = [self.resolveType(pt, sym.scope) for pt in ft.parametertypes] |
226 | 114 elif type(sym) is DefinedType: |
115 sym.typ = self.resolveType(sym.typ, sym.scope) | |
215 | 116 |
117 def sanity(self, sym): | |
118 if type(sym) is FunctionType: | |
119 pass | |
120 elif type(sym) is Function: | |
121 pass | |
122 |