diff 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
line wrap: on
line diff
--- a/python/ppci/c3/scope.py	Fri Dec 06 13:50:38 2013 +0100
+++ b/python/ppci/c3/scope.py	Mon Dec 09 19:00:21 2013 +0100
@@ -1,8 +1,9 @@
-from . import astnodes
+from .astnodes import Constant, Variable, Function, BaseType
 
 
 class Scope:
-    """ A scope contains all symbols in a scope """
+    """ A scope contains all symbols in a scope. It also has a parent scope,
+        when looking for a symbol, also the parent scopes are checked. """
     def __init__(self, parent=None):
         self.symbols = {}
         self.parent = parent
@@ -18,53 +19,58 @@
 
     @property
     def Constants(self):
-        return [s for s in self.Syms if type(s) is astnodes.Constant]
+        return [s for s in self.Syms if type(s) is Constant]
 
     @property
     def Variables(self):
-        return [s for s in self.Syms if isinstance(s, astnodes.Variable)]
+        return [s for s in self.Syms if isinstance(s, Variable)]
 
     @property
     def Functions(self):
-        return [s for s in self.Syms if type(s) is astnodes.Function]
+        return [s for s in self.Syms if type(s) is Function]
 
     def getSymbol(self, name):
         if name in self.symbols:
             return self.symbols[name]
         # Look for symbol:
-        if self.parent:
+        elif self.parent:
             return self.parent.getSymbol(name)
-        raise CompilerException("Symbol {0} not found".format(name), name.loc)
+        else:
+            raise KeyError(name)
+
+    def __getitem__(self, key):
+        return self.getSymbol(key)
 
     def hasSymbol(self, name):
         if name in self.symbols:
             return True
-        if self.parent:
+        elif self.parent:
             return self.parent.hasSymbol(name)
-        return False
+        else:
+            return False
+
+    def __contains__(self, name):
+        return self.hasSymbol(name)
 
     def addSymbol(self, sym):
+        assert sym.name not in self.symbols
         self.symbols[sym.name] = sym
 
     def __repr__(self):
         return 'Scope with {} symbols'.format(len(self.symbols))
 
 
-def createBuiltins(scope):
+def createTopScope(target):
+    scope = Scope()
     for tn in ['u64', 'u32', 'u16', 'u8']:
-        scope.addSymbol(astnodes.BaseType(tn))
-    for t in [intType, doubleType, voidType, boolType, stringType, byteType]:
-        scope.addSymbol(t)
-
-# buildin types:
-intType = astnodes.BaseType('int')
-intType.bytesize = 4
-doubleType = astnodes.BaseType('double')
-voidType = astnodes.BaseType('void')
-boolType = astnodes.BaseType('bool')
-stringType = astnodes.BaseType('string')
-byteType = astnodes.BaseType('byte')
-
-# Create top level scope:
-topScope = Scope()
-createBuiltins(topScope)
+        scope.addSymbol(BaseType(tn))
+    # buildin types:
+    intType = BaseType('int')
+    intType.bytesize = target.byte_sizes['int']
+    scope.addSymbol(intType)
+    scope.addSymbol(BaseType('double'))
+    scope.addSymbol(BaseType('void'))
+    scope.addSymbol(BaseType('bool'))
+    scope.addSymbol(BaseType('string'))
+    scope.addSymbol(BaseType('byte'))
+    return scope