Mercurial > lcfOS
view python/c3/analyse.py @ 215:c1ccb1cb4cef
Major changes in c3 frontend
author | Windel Bouwman |
---|---|
date | Fri, 05 Jul 2013 13:00:03 +0200 |
parents | 46d62dadd61b |
children | 8b2e5f3cd579 |
line wrap: on
line source
from .visitor import Visitor from .astnodes import * from .scope import Scope, topScope class Analyzer: """ Context handling is done here. Scope is attached to the correct modules. This class checks names and references """ def __init__(self, diag): self.diag = diag def analyzePackage(self, pkg): self.ok = True visitor = Visitor() # Prepare top level scope: self.curScope = topScope visitor.visit(pkg, self.enterScope, self.quitScope) del self.curScope visitor.visit(pkg, self.findRefs) visitor.visit(pkg, self.sanity) return self.ok def error(self, msg, loc=None): self.ok = False self.diag.error(msg, loc) # Scope creation: def addSymbol(self, sym): if self.curScope.hasSymbol(sym.name): self.error('Redefinition of {0}'.format(sym.name), sym.loc) else: self.curScope.addSymbol(sym) def enterScope(self, sym): # Distribute the scope: sym.scope = self.curScope # Add symbols to current scope: if isinstance(sym, Symbol): self.addSymbol(sym) # Create subscope: if type(sym) in [Package, Function]: self.curScope = Scope(self.curScope) def quitScope(self, sym): # Pop out of scope: if type(sym) in [Package, Function]: self.curScope = self.curScope.parent # Reference fixups: def resolveDesignator(self, d, scope): assert type(d) is Designator assert type(scope) is Scope if scope.hasSymbol(d.tname): s = scope.getSymbol(d.tname) if hasattr(s, 'addRef'): # TODO: make this nicer s.addRef(None) return s else: self.ok = False msg = 'Cannot resolve name {0}'.format(d.tname) self.diag.error(msg, d.loc) def findRefs(self, sym): if type(sym) in [Variable, Constant]: sym.typ = self.resolveDesignator(sym.typ, sym.scope) elif type(sym) is VariableUse: sym.target = self.resolveDesignator(sym.target, sym.scope) elif type(sym) is FunctionCall: sym.proc = self.resolveDesignator(sym.proc, 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] def sanity(self, sym): if type(sym) is FunctionType: pass elif type(sym) is Function: pass