Mercurial > lcfOS
diff python/c3/semantics.py @ 150:4ae0e02599de
Added type check start and analyze phase
author | Windel Bouwman |
---|---|
date | Fri, 01 Mar 2013 16:53:22 +0100 |
parents | 74241ca312cc |
children | b73bc14a3aa3 |
line wrap: on
line diff
--- a/python/c3/semantics.py Fri Mar 01 11:43:52 2013 +0100 +++ b/python/c3/semantics.py Fri Mar 01 16:53:22 2013 +0100 @@ -1,46 +1,49 @@ from . import astnodes - -class Scope: - """ A scope contains all symbols in a scope """ - def __init__(self, parent=None): - self.symbols = {} - self.parent = parent - def __iter__(self): - return iter(self.symbols.values()) - def getType(self, name): - t = self.getSymbol(name) - print(t) - assert isinstance(t, astnodes.Type) - return t - def getSymbol(self, name): - if name in self.symbols: - return self.symbols[name] - # Look for symbol: - if self.parent: - return self.parent.getSymbol(name) - raise CompilerException("Symbol {0} not found".format(name), name.loc) - def hasSymbol(self, name): - if name in self.symbols: - return True - if self.parent: - return self.parent.hasSymbol(name) - return False - - def addSymbol(self, sym): - self.symbols[sym.name] = sym - -def createBuiltins(scope): - scope.addSymbol(astnodes.BaseType('int')) +from .scope import Scope, topScope +from ppci.errors import CompilerException class Semantics: """ This class constructs the AST from parser input """ def __init__(self, diag): self.diag = diag + def addSymbol(self, s): + if self.curScope.hasSymbol(s.name): + msg = 'Redefinition of {0}'.format(s.name) + self.diag.diag(CompilerException(msg, s.loc)) + else: + self.curScope.addSymbol(s) def handlePackage(self, name, loc): self.mod = astnodes.Package(name) self.mod.loc = loc - self.mod.scope = self.curScope = Scope() - createBuiltins(self.curScope) + self.mod.scope = self.curScope = Scope(topScope) + def actOnVarDef(self, name, loc, t, ival): + s = astnodes.Variable(name, t) + s.loc = loc + self.addSymbol(s) + def actOnFuncDef1(self, name, loc): + self.curFunc = astnodes.Function(name) + self.curFunc.loc = loc + self.addSymbol(self.curFunc) + self.curScope = self.curFunc.scope = Scope(self.curScope) + def actOnParameter(self, name, loc, t): + p = astnodes.Variable(name, t) + p.loc = loc + p.parameter = True + self.addSymbol(p) + return p + def actOnFuncDef2(self, parameters, returntype, body): + self.curFunc.body = body + self.curFunc.typ = astnodes.FunctionType(parameters, returntype) + self.curFunc = None + self.curScope = self.curScope.parent + def actOnType(self, tok): + # Try to lookup type, in case of failure return void + pass + def actOnDesignator(self, tname, loc): + d = astnodes.Designator(tname) + d.scope = self.curScope + d.loc = loc + return d def actOnBinop(self, lhs, op, rhs, loc): bo = astnodes.Binop(lhs, op, rhs) bo.loc = loc @@ -49,21 +52,6 @@ n = astnodes.Constant(num) n.loc = loc return n - def actOnVarDef(self, name, loc, t, ival): - s = astnodes.Variable(name, t) - s.loc = loc - self.curScope.addSymbol(s) - def actOnFuncDef1(self, name, loc): - self.curFunc = astnodes.Procedure(name) - self.curFunc.loc = loc - self.curScope.addSymbol(self.curFunc) - self.curScope = self.curFunc.scope = Scope(self.curScope) - def actOnFuncDef2(self, parameters, returntype, body): - self.curFunc.body = body - self.curFunc.typ = astnodes.FunctionType(parameters, returntype) - self.curFunc = None - self.curScope = self.curScope.parent - def actOnType(self, tok): - # Try to lookup type, in case of failure return void - pass + def actOnVariableUse(self, d): + return astnodes.VariableUse(d)