Commits

Gigih Aji Ibrahim committed 3c1c06c

bugfix for bad codegen when use class from other module

Comments (0)

Files changed (6)

src/ast3/symbol.py

 
         super(Symbol, self).__init__(src)
         self.name = name
+        self.owner = None
+
+    def parentModule(self):
+        """ get module symbol where this symbol reside """
+        assert self.owner != None, "self.owner cannot None (self=={})".format(self)
+
+        sym = self.owner
+        while not isinstance(sym, Module) and sym is not None:
+            sym = sym.owner
+
+        return sym
 
 
 class ScopeSymbol(Symbol):
         ## dictionaries of { string name : Symbol instance }
         self._symbolTable = {}
 
-        self.owner = None
 
-    def parentModule(self):
-        """ get module symbol where this method reside """
-
-        sym = self.owner
-        if sym != None and not isinstance(sym, Module):
-            sym = sym.owner
-
-        return sym
 
     def insert(self, name, symbol=None, owned=True):
         """
         self.importDecls.extend(parseResult.importDecls)
         self.decls.extend(parseResult.decls)
 
+    def parentModule(self): return None
+
 
 class Interface(ScopeSymbol):
     """ Inteface symbol only contain abstract method """
         self.name = name
         self.typeArgs = typeArgs
         self.left = left
+        
+    def __str__(self):
+        text = ""
+        if self.left:
+            text = str(self.left) + '.'
+        text += self.name
+        return text
 
 
 class RangeType(Type):
     
     def pExtendDecl(self):
         token = self.current
-        name  = self.getName()
+        name  = self.pNameType()
         args  = self.groupAction(self.pExpr, allowSingle=False) if self.peekNext().type == '(' else []
         return ExtendDecl(self.getLoc(token), name, args)
     

src/pygen/generator.py

             if not hasattr(symbol, 'symbol'): 
                 raise CodeGenError(None, "NYI: toPyName() with args: type without symbol attr")
 
-            symbol = symbol.symbol
-            qualifiedname = self.toPyName(symbol)
+            return self.toPyName(symbol.symbol)
+        
+        elif isinstance(symbol, Symbol):
+            ## local var symbol
+            if isinstance(symbol, Var) and symbol.isLocal():
+                return "__L{0}".format(symbol.name)
 
-            ## symbol from other module
-            if isinstance(symbol, ScopeSymbol) and symbol.parentModule() != self.modul:
+            ## extern symbol
+            if hasattr(symbol, 'flags') and symbol.flags is not None and symbol.flags.get('extern') is not None:
+                return symbol.flags.get('extern')
+
+            ## special symbol
+            if isA(symbol, BSymbol):
+                return 'rt.type.' + symbol.name
+            
+            ## Param
+            if isA(symbol, Param):
+                return symbol.name
+
+            ## scope symbol
+            if symbol.parentModule() != self.modul:
+                qualifiedname = symbol.name
                 while symbol.owner != None:
                     symbol = symbol.owner
                     qualifiedname = "{0}.{1}".format(symbol.name,qualifiedname)
-
-            return qualifiedname
-                
-
-        ## local var symbol
-        if isinstance(symbol, Var) and symbol.isLocal():
-            return "__L{0}".format(symbol.name)
-
-        ## extern symbol
-        if hasattr(symbol, 'flags') and symbol.flags is not None and symbol.flags.get('extern') is not None:
-            return symbol.flags.get('extern')
-
-        ## special symbol
-        if isA(symbol, BSymbol):
-            return 'rt.type.' + symbol.name
+                return qualifiedname
+            
         
         ## other symbol
         return symbol.name
 
     def vNameExpr(self, node):
 
-        pyname = self.toPyName(node.symbol)
-
         ## we add 'self.' to name if it is not DotExpr
         structOrClass = isA(node.symbol.owner, Struct, Class)
         if isA(node.symbol, ConstructParam) and '$' in node.symbol.marks:
-            self.var(pyname)
+            self.var(self.toPyName(node.symbol))
         elif structOrClass and node.left == None:
-            self.var('self.' + pyname)
+            self.var('self.' + node.symbol.name)
         elif node.left != None:
             with self.wrap(PyBinaryExpr('.')):
                 self.visit(node.left)
-                self.var(pyname)
+                self.var(node.symbol.name)
         else:
+            pyname = self.toPyName(node.symbol)
             self.var(pyname)
 
 

src/step/resolver.py

         ## visit all delayed node
         for (node, stack) in self._delayedNodes:
             self.modul = stack[0]
-
             self.restore(stack)
             try: self.visit(node)
-            except SemanticError, ex: report.error(ex)
+            except SemanticError as ex: report.error(ex)
             self.reset()
 
 
         
         
     def vExtendDecl(self, node):
-        symbol = self.search(node.name)
+        self.visit(node.name)
+        symbol = node.name.symbol
         
         ## check undefined symbol or not class symbol
         if symbol == None:
-            raise SemanticError(node.loc, "Cannot find symbol {0}".format(node.name))
+            raise SemanticError(node.name.loc, "Cannot find symbol {0}".format(node.name))
         elif not isinstance(symbol, Class):
-            raise SemanticError(node.loc, "cannot extend from {0}, symbol is not class".format(node.name))
+            raise SemanticError(node.name.loc, "cannot extend from {0}, symbol is not class".format(node.name))
 
         classSymbol = self.searchByType(Class)
         
         ## insert to current class
         classSymbol.addExtend(symbol, node.args)
  
+
+    def vNameType(self, node):
+        self.visit(node.left)
+        
+        if node.left != None: self.pushSymbol(node.left.symbol)
+        node.symbol = self.search(node.name)
+        if node.left != None: self.popSymbol()
+
+        

src/step/typechecker.py

                 if len(node) == 1 and not isinstance(node[0], ReturnStmt):
                     node[0].parent.stmts[0] = self.wrapReturnStmt(node[0])
 
-            except SemanticError, ex:
+            except SemanticError as ex:
                 report.error(ex)
 
             self.reset()