Mercurial > lcfOS
comparison python/c3/analyse.py @ 220:3f6c30a5d234
Major change in expression parsing to enable pointers and structs
author | Windel Bouwman |
---|---|
date | Sat, 06 Jul 2013 21:32:20 +0200 |
parents | 8b2e5f3cd579 |
children | c3f1ce8b638f |
comparison
equal
deleted
inserted
replaced
219:1fa3e0050b49 | 220:3f6c30a5d234 |
---|---|
13 | 13 |
14 def analyzePackage(self, pkg): | 14 def analyzePackage(self, pkg): |
15 self.ok = True | 15 self.ok = True |
16 visitor = Visitor() | 16 visitor = Visitor() |
17 # Prepare top level scope: | 17 # Prepare top level scope: |
18 self.curScope = topScope | 18 self.scopeStack = [topScope] |
19 visitor.visit(pkg, self.enterScope, self.quitScope) | 19 visitor.visit(pkg, self.enterScope, self.quitScope) |
20 del self.curScope | 20 del self.scopeStack |
21 visitor.visit(pkg, self.findRefs) | 21 visitor.visit(pkg, self.findRefs) |
22 visitor.visit(pkg, self.sanity) | 22 visitor.visit(pkg, self.sanity) |
23 return self.ok | 23 return self.ok |
24 | 24 |
25 def error(self, msg, loc=None): | 25 def error(self, msg, loc=None): |
26 self.ok = False | 26 self.ok = False |
27 self.diag.error(msg, loc) | 27 self.diag.error(msg, loc) |
28 | 28 |
29 @property | |
30 def currentScope(self): | |
31 return self.scopeStack[-1] | |
32 | |
29 # Scope creation: | 33 # Scope creation: |
30 def addSymbol(self, sym): | 34 def addSymbol(self, sym): |
31 if self.curScope.hasSymbol(sym.name): | 35 if self.currentScope.hasSymbol(sym.name): |
32 self.error('Redefinition of {0}'.format(sym.name), sym.loc) | 36 self.error('Redefinition of {0}'.format(sym.name), sym.loc) |
33 else: | 37 else: |
34 self.curScope.addSymbol(sym) | 38 self.currentScope.addSymbol(sym) |
35 | 39 |
36 def enterScope(self, sym): | 40 def enterScope(self, sym): |
37 # Distribute the scope: | 41 # Distribute the scope: |
38 sym.scope = self.curScope | 42 sym.scope = self.currentScope |
39 | 43 |
40 # Add symbols to current scope: | 44 # Add symbols to current scope: |
41 if isinstance(sym, Symbol): | 45 if isinstance(sym, Symbol): |
42 self.addSymbol(sym) | 46 self.addSymbol(sym) |
43 | 47 |
44 # Create subscope: | 48 # Create subscope: |
45 if type(sym) in [Package, Function]: | 49 if type(sym) in [Package, Function]: |
46 self.curScope = Scope(self.curScope) | 50 newScope = Scope(self.currentScope) |
47 sym.innerScope = self.curScope | 51 self.scopeStack.append(newScope) |
52 sym.innerScope = self.currentScope | |
48 | 53 |
49 def quitScope(self, sym): | 54 def quitScope(self, sym): |
50 # Pop out of scope: | 55 # Pop out of scope: |
51 if type(sym) in [Package, Function]: | 56 if type(sym) in [Package, Function]: |
52 self.curScope = self.curScope.parent | 57 self.scopeStack.pop(-1) |
53 | 58 |
54 # Reference fixups: | 59 # Reference fixups: |
55 def resolveDesignator(self, d, scope): | 60 def resolveDesignator(self, d, scope): |
56 assert type(d) is Designator | 61 assert type(d) is Designator, type(d) |
57 assert type(scope) is Scope | 62 assert type(scope) is Scope |
58 if scope.hasSymbol(d.tname): | 63 if scope.hasSymbol(d.tname): |
59 s = scope.getSymbol(d.tname) | 64 s = scope.getSymbol(d.tname) |
60 if hasattr(s, 'addRef'): | 65 if hasattr(s, 'addRef'): |
61 # TODO: make this nicer | 66 # TODO: make this nicer |
64 else: | 69 else: |
65 self.ok = False | 70 self.ok = False |
66 msg = 'Cannot resolve name {0}'.format(d.tname) | 71 msg = 'Cannot resolve name {0}'.format(d.tname) |
67 self.diag.error(msg, d.loc) | 72 self.diag.error(msg, d.loc) |
68 | 73 |
74 def resolveType(self, t, scope): | |
75 # TODO: what about structs? | |
76 if type(t) is PointerType: | |
77 t.ptype = self.resolveType(t.ptype, scope) | |
78 return t | |
79 elif type(t) is Designator: | |
80 return self.resolveDesignator(t, scope) | |
81 else: | |
82 print('ERR resolve type!') | |
83 | |
69 def findRefs(self, sym): | 84 def findRefs(self, sym): |
70 if type(sym) in [Variable, Constant]: | 85 if type(sym) in [Variable, Constant]: |
71 sym.typ = self.resolveDesignator(sym.typ, sym.scope) | 86 sym.typ = self.resolveType(sym.typ, sym.scope) |
72 elif type(sym) is VariableUse: | 87 elif type(sym) is VariableUse: |
73 sym.target = self.resolveDesignator(sym.target, sym.scope) | 88 sym.target = self.resolveDesignator(sym.target, sym.scope) |
74 elif type(sym) is FunctionCall: | 89 elif type(sym) is FunctionCall: |
75 sym.proc = self.resolveDesignator(sym.proc, sym.scope) | 90 varuse = sym.proc |
91 sym.proc = self.resolveDesignator(varuse.target, sym.scope) | |
76 elif type(sym) is Function: | 92 elif type(sym) is Function: |
77 # Checkup function type: | 93 # Checkup function type: |
78 ft = sym.typ | 94 ft = sym.typ |
79 ft.returntype = self.resolveDesignator(ft.returntype, sym.scope) | 95 ft.returntype = self.resolveType(ft.returntype, sym.scope) |
80 ft.parametertypes = [self.resolveDesignator(pt, sym.scope) for pt in ft.parametertypes] | 96 ft.parametertypes = [self.resolveType(pt, sym.scope) for pt in ft.parametertypes] |
81 | 97 |
82 def sanity(self, sym): | 98 def sanity(self, sym): |
83 if type(sym) is FunctionType: | 99 if type(sym) is FunctionType: |
84 pass | 100 pass |
85 elif type(sym) is Function: | 101 elif type(sym) is Function: |