comparison 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
comparison
equal deleted inserted replaced
162:d8c735dc31f9 163:8104fc8b5e90
1 from .astnodes import BaseType, Variable, Designator, Function 1 from .astnodes import *
2 from .astnodes import CompoundStatement, Assignment, VariableUse 2 from .scope import *
3 from .astnodes import Binop, Unop, Constant 3 from .visitor import Visitor
4 from .astnodes import IfStatement, WhileStatement, ReturnStatement, ProcedureCall 4
5 from .astnodes import FunctionType, BaseType 5 def equalTypes(a, b):
6 from . import astnodes 6 """ Compare types a and b for equality. Not equal until proven otherwise. """
7 from .scope import topScope 7 if type(a) is type(b):
8 if type(a) is BaseType:
9 return a.name == b.name
10 return False
8 11
9 class TypeChecker: 12 class TypeChecker:
10 def __init__(self, diag): 13 def __init__(self, diag):
11 self.diag = diag 14 self.diag = diag
15 self.visitor = Visitor(self.precheck, self.check2)
12 def checkPackage(self, pkg): 16 def checkPackage(self, pkg):
13 for s in pkg.scope: 17 self.visitor.visit(pkg)
14 self.check(s) 18 def precheck(self, sym):
15 def resolveDesignator(self, d): 19 pass
16 if d.scope.hasSymbol(d.tname): 20 def check2(self, sym):
17 return d.scope.getSymbol(d.tname) 21 if type(sym) is Function:
22 pass
23 elif type(sym) is IfStatement:
24 print(sym.condition)
25 if not equalTypes(sym.condition.typ, boolType):
26 self.diag.error('Condition must be a boolean expression', sym.condition.loc)
27 elif type(sym) is Assignment:
28 pass
29 elif type(sym) is ReturnStatement:
30 pass
31 elif type(sym) is ProcedureCall:
32 # Check arguments:
33
34 # determine return type:
35 sym.typ = sym.proc.typ.returntype
36 elif type(sym) is VariableUse:
37 if sym.target:
38 sym.typ = sym.target.typ
39 else:
40 sym.typ = voidType
41 elif type(sym) is Literal:
42 if type(sym.val) is int:
43 sym.typ = intType
44 elif type(sym.val) is float:
45 sym.typ = doubleType
46 else:
47 self.diag.error('Unknown literal type', sym.loc)
48 elif type(sym) is Binop:
49 if sym.op in ['+', '-', '*', '/']:
50 if equalTypes(sym.a.typ, sym.b.typ):
51 sym.typ = sym.a.typ
52 else:
53 # assume void here?
54 sym.typ = voidType
55 self.diag.error('Types unequal', sym.loc)
56 elif sym.op in ['>', '<']:
57 if equalTypes(sym.a.typ, sym.b.typ):
58 sym.typ = boolType
59 else:
60 sym.typ = voidType
61 self.diag.error('Types unequal', sym.loc)
62 else:
63 sym.typ = voidType
64 print('unknown binop', sym.op)
18 else: 65 else:
19 msg = 'Cannot resolve name {0}'.format(d.tname) 66 print('Unknown type check', sym)
20 self.diag.error(msg, d.loc)
21 def check(self, sym):
22 if type(sym) is Variable:
23 if type(sym.typ) is Designator:
24 sym.typ = self.resolveDesignator(sym.typ)
25 elif type(sym) is Function:
26 for s in sym.scope:
27 self.check(s)
28 self.check(sym.typ)
29 self.check(sym.body)
30 elif type(sym) is CompoundStatement:
31 for s in sym.statements:
32 self.check(s)
33 elif type(sym) is IfStatement:
34 self.check(sym.condition)
35 self.check(sym.truestatement)
36 self.check(sym.falsestatement)
37 elif type(sym) is VariableUse:
38 if type(sym.target) is Designator:
39 sym.target = self.resolveDesignator(sym.target)
40 elif type(sym) is ProcedureCall:
41 if type(sym.proc) is Designator:
42 sym.proc = self.resolveDesignator(sym.proc)
43 elif type(sym) is Assignment:
44 self.check(sym.lval)
45 self.check(sym.rval)
46 elif type(sym) is ReturnStatement:
47 self.check(sym.expr)
48 elif type(sym) is Constant:
49 if type(sym.value) is int:
50 sym.typ = topScope.getSymbol('int')
51 elif type(sym) is FunctionType:
52 if type(sym.returntype) is Designator:
53 sym.returntype = self.resolveDesignator(sym.returntype)
54 self.check(sym.returntype)
55 elif type(sym) is Binop:
56 self.check(sym.a)
57 self.check(sym.b)
58 if type(sym.a) is Constant and type(sym.b) is Constant:
59 # Possibly fold expression
60 pass
61 67