Mercurial > lcfOS
view python/c3/typecheck.py @ 163:8104fc8b5e90
Added visitor to c3
author | Windel Bouwman |
---|---|
date | Mon, 18 Mar 2013 20:13:57 +0100 |
parents | b28a11c01dbe |
children | e023d3ce1d63 |
line wrap: on
line source
from .astnodes import * from .scope import * from .visitor import Visitor def equalTypes(a, b): """ Compare types a and b for equality. Not equal until proven otherwise. """ if type(a) is type(b): if type(a) is BaseType: return a.name == b.name return False class TypeChecker: def __init__(self, diag): self.diag = diag self.visitor = Visitor(self.precheck, self.check2) def checkPackage(self, pkg): self.visitor.visit(pkg) def precheck(self, sym): pass def check2(self, sym): if type(sym) is Function: pass elif type(sym) is IfStatement: print(sym.condition) if not equalTypes(sym.condition.typ, boolType): self.diag.error('Condition must be a boolean expression', sym.condition.loc) elif type(sym) is Assignment: pass elif type(sym) is ReturnStatement: pass elif type(sym) is ProcedureCall: # Check arguments: # determine return type: sym.typ = sym.proc.typ.returntype elif type(sym) is VariableUse: if sym.target: sym.typ = sym.target.typ else: sym.typ = voidType elif type(sym) is Literal: if type(sym.val) is int: sym.typ = intType elif type(sym.val) is float: sym.typ = doubleType else: self.diag.error('Unknown literal type', sym.loc) elif type(sym) is Binop: if sym.op in ['+', '-', '*', '/']: if equalTypes(sym.a.typ, sym.b.typ): sym.typ = sym.a.typ else: # assume void here? sym.typ = voidType self.diag.error('Types unequal', sym.loc) elif sym.op in ['>', '<']: if equalTypes(sym.a.typ, sym.b.typ): sym.typ = boolType else: sym.typ = voidType self.diag.error('Types unequal', sym.loc) else: sym.typ = voidType print('unknown binop', sym.op) else: print('Unknown type check', sym)