comparison python/ppci/c3/scope.py @ 306:b145f8e6050b

Start on c3 rewrite
author Windel Bouwman
date Mon, 09 Dec 2013 19:00:21 +0100
parents 158068af716c
children e609d5296ee9
comparison
equal deleted inserted replaced
305:0615b5308710 306:b145f8e6050b
1 from . import astnodes 1 from .astnodes import Constant, Variable, Function, BaseType
2 2
3 3
4 class Scope: 4 class Scope:
5 """ A scope contains all symbols in a scope """ 5 """ A scope contains all symbols in a scope. It also has a parent scope,
6 when looking for a symbol, also the parent scopes are checked. """
6 def __init__(self, parent=None): 7 def __init__(self, parent=None):
7 self.symbols = {} 8 self.symbols = {}
8 self.parent = parent 9 self.parent = parent
9 10
10 def __iter__(self): 11 def __iter__(self):
16 syms = self.symbols.values() 17 syms = self.symbols.values()
17 return sorted(syms, key=lambda v: v.name) 18 return sorted(syms, key=lambda v: v.name)
18 19
19 @property 20 @property
20 def Constants(self): 21 def Constants(self):
21 return [s for s in self.Syms if type(s) is astnodes.Constant] 22 return [s for s in self.Syms if type(s) is Constant]
22 23
23 @property 24 @property
24 def Variables(self): 25 def Variables(self):
25 return [s for s in self.Syms if isinstance(s, astnodes.Variable)] 26 return [s for s in self.Syms if isinstance(s, Variable)]
26 27
27 @property 28 @property
28 def Functions(self): 29 def Functions(self):
29 return [s for s in self.Syms if type(s) is astnodes.Function] 30 return [s for s in self.Syms if type(s) is Function]
30 31
31 def getSymbol(self, name): 32 def getSymbol(self, name):
32 if name in self.symbols: 33 if name in self.symbols:
33 return self.symbols[name] 34 return self.symbols[name]
34 # Look for symbol: 35 # Look for symbol:
35 if self.parent: 36 elif self.parent:
36 return self.parent.getSymbol(name) 37 return self.parent.getSymbol(name)
37 raise CompilerException("Symbol {0} not found".format(name), name.loc) 38 else:
39 raise KeyError(name)
40
41 def __getitem__(self, key):
42 return self.getSymbol(key)
38 43
39 def hasSymbol(self, name): 44 def hasSymbol(self, name):
40 if name in self.symbols: 45 if name in self.symbols:
41 return True 46 return True
42 if self.parent: 47 elif self.parent:
43 return self.parent.hasSymbol(name) 48 return self.parent.hasSymbol(name)
44 return False 49 else:
50 return False
51
52 def __contains__(self, name):
53 return self.hasSymbol(name)
45 54
46 def addSymbol(self, sym): 55 def addSymbol(self, sym):
56 assert sym.name not in self.symbols
47 self.symbols[sym.name] = sym 57 self.symbols[sym.name] = sym
48 58
49 def __repr__(self): 59 def __repr__(self):
50 return 'Scope with {} symbols'.format(len(self.symbols)) 60 return 'Scope with {} symbols'.format(len(self.symbols))
51 61
52 62
53 def createBuiltins(scope): 63 def createTopScope(target):
64 scope = Scope()
54 for tn in ['u64', 'u32', 'u16', 'u8']: 65 for tn in ['u64', 'u32', 'u16', 'u8']:
55 scope.addSymbol(astnodes.BaseType(tn)) 66 scope.addSymbol(BaseType(tn))
56 for t in [intType, doubleType, voidType, boolType, stringType, byteType]: 67 # buildin types:
57 scope.addSymbol(t) 68 intType = BaseType('int')
58 69 intType.bytesize = target.byte_sizes['int']
59 # buildin types: 70 scope.addSymbol(intType)
60 intType = astnodes.BaseType('int') 71 scope.addSymbol(BaseType('double'))
61 intType.bytesize = 4 72 scope.addSymbol(BaseType('void'))
62 doubleType = astnodes.BaseType('double') 73 scope.addSymbol(BaseType('bool'))
63 voidType = astnodes.BaseType('void') 74 scope.addSymbol(BaseType('string'))
64 boolType = astnodes.BaseType('bool') 75 scope.addSymbol(BaseType('byte'))
65 stringType = astnodes.BaseType('string') 76 return scope
66 byteType = astnodes.BaseType('byte')
67
68 # Create top level scope:
69 topScope = Scope()
70 createBuiltins(topScope)