diff 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
line wrap: on
line diff
--- a/python/c3/analyse.py	Sat Jul 06 12:38:09 2013 +0200
+++ b/python/c3/analyse.py	Sat Jul 06 21:32:20 2013 +0200
@@ -15,9 +15,9 @@
         self.ok = True
         visitor = Visitor()
         # Prepare top level scope:
-        self.curScope = topScope
+        self.scopeStack = [topScope]
         visitor.visit(pkg, self.enterScope, self.quitScope)
-        del self.curScope
+        del self.scopeStack
         visitor.visit(pkg, self.findRefs)
         visitor.visit(pkg, self.sanity)
         return self.ok
@@ -26,16 +26,20 @@
         self.ok = False
         self.diag.error(msg, loc)
 
+    @property
+    def currentScope(self):
+        return self.scopeStack[-1]
+
     # Scope creation:
     def addSymbol(self, sym):
-        if self.curScope.hasSymbol(sym.name):
+        if self.currentScope.hasSymbol(sym.name):
             self.error('Redefinition of {0}'.format(sym.name), sym.loc)
         else:
-            self.curScope.addSymbol(sym)
+            self.currentScope.addSymbol(sym)
 
     def enterScope(self, sym):
         # Distribute the scope:
-        sym.scope = self.curScope
+        sym.scope = self.currentScope
 
         # Add symbols to current scope:
         if isinstance(sym, Symbol):
@@ -43,17 +47,18 @@
 
         # Create subscope:
         if type(sym) in [Package, Function]:
-            self.curScope = Scope(self.curScope)
-            sym.innerScope = self.curScope
+            newScope = Scope(self.currentScope)
+            self.scopeStack.append(newScope)
+            sym.innerScope = self.currentScope
 
     def quitScope(self, sym):
         # Pop out of scope:
         if type(sym) in [Package, Function]:
-            self.curScope = self.curScope.parent
+            self.scopeStack.pop(-1)
 
     # Reference fixups:
     def resolveDesignator(self, d, scope):
-        assert type(d) is Designator
+        assert type(d) is Designator, type(d)
         assert type(scope) is Scope
         if scope.hasSymbol(d.tname):
             s = scope.getSymbol(d.tname)
@@ -66,18 +71,29 @@
             msg = 'Cannot resolve name {0}'.format(d.tname)
             self.diag.error(msg, d.loc)
 
+    def resolveType(self, t, scope):
+        # TODO: what about structs?
+        if type(t) is PointerType:
+            t.ptype = self.resolveType(t.ptype, scope)
+            return t
+        elif type(t) is Designator:
+            return self.resolveDesignator(t, scope)
+        else:
+            print('ERR resolve type!')
+        
     def findRefs(self, sym):
         if type(sym) in [Variable, Constant]:
-             sym.typ = self.resolveDesignator(sym.typ, sym.scope)
+            sym.typ = self.resolveType(sym.typ, sym.scope)
         elif type(sym) is VariableUse:
-             sym.target = self.resolveDesignator(sym.target, sym.scope)
+            sym.target = self.resolveDesignator(sym.target, sym.scope)
         elif type(sym) is FunctionCall:
-             sym.proc = self.resolveDesignator(sym.proc, sym.scope)
+            varuse = sym.proc
+            sym.proc = self.resolveDesignator(varuse.target, sym.scope)
         elif type(sym) is Function:
             # Checkup function type:
             ft = sym.typ
-            ft.returntype = self.resolveDesignator(ft.returntype, sym.scope)
-            ft.parametertypes = [self.resolveDesignator(pt, sym.scope) for pt in ft.parametertypes]
+            ft.returntype = self.resolveType(ft.returntype, sym.scope)
+            ft.parametertypes = [self.resolveType(pt, sym.scope) for pt in ft.parametertypes]
 
     def sanity(self, sym):
         if type(sym) is FunctionType: