Mercurial > lcfOS
view python/c3/typecheck.py @ 162:d8c735dc31f9
Used new editor in ide
author | Windel Bouwman |
---|---|
date | Sun, 10 Mar 2013 11:36:55 +0100 |
parents | b28a11c01dbe |
children | 8104fc8b5e90 |
line wrap: on
line source
from .astnodes import BaseType, Variable, Designator, Function from .astnodes import CompoundStatement, Assignment, VariableUse from .astnodes import Binop, Unop, Constant from .astnodes import IfStatement, WhileStatement, ReturnStatement, ProcedureCall from .astnodes import FunctionType, BaseType from . import astnodes from .scope import topScope class TypeChecker: def __init__(self, diag): self.diag = diag def checkPackage(self, pkg): for s in pkg.scope: self.check(s) def resolveDesignator(self, d): if d.scope.hasSymbol(d.tname): return d.scope.getSymbol(d.tname) else: msg = 'Cannot resolve name {0}'.format(d.tname) self.diag.error(msg, d.loc) def check(self, sym): if type(sym) is Variable: if type(sym.typ) is Designator: sym.typ = self.resolveDesignator(sym.typ) elif type(sym) is Function: for s in sym.scope: self.check(s) self.check(sym.typ) self.check(sym.body) elif type(sym) is CompoundStatement: for s in sym.statements: self.check(s) elif type(sym) is IfStatement: self.check(sym.condition) self.check(sym.truestatement) self.check(sym.falsestatement) elif type(sym) is VariableUse: if type(sym.target) is Designator: sym.target = self.resolveDesignator(sym.target) elif type(sym) is ProcedureCall: if type(sym.proc) is Designator: sym.proc = self.resolveDesignator(sym.proc) elif type(sym) is Assignment: self.check(sym.lval) self.check(sym.rval) elif type(sym) is ReturnStatement: self.check(sym.expr) elif type(sym) is Constant: if type(sym.value) is int: sym.typ = topScope.getSymbol('int') elif type(sym) is FunctionType: if type(sym.returntype) is Designator: sym.returntype = self.resolveDesignator(sym.returntype) self.check(sym.returntype) elif type(sym) is Binop: self.check(sym.a) self.check(sym.b) if type(sym.a) is Constant and type(sym.b) is Constant: # Possibly fold expression pass