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: