150
|
1 from .astnodes import BaseType, Variable, Designator, Function
|
|
2 from .astnodes import CompoundStatement, Assignment, VariableUse
|
|
3 from .astnodes import Binop, Unop, Constant
|
|
4 from .astnodes import IfStatement, WhileStatement, ReturnStatement
|
|
5 from .astnodes import FunctionType, BaseType
|
|
6 from . import astnodes
|
|
7 from .scope import topScope
|
|
8
|
|
9 class TypeChecker:
|
|
10 def __init__(self, diag):
|
|
11 self.diag = diag
|
|
12 def checkPackage(self, pkg):
|
|
13 for s in pkg.scope:
|
|
14 self.check(s)
|
|
15 def resolveDesignator(self, d):
|
|
16 if d.scope.hasSymbol(d.tname):
|
|
17 return d.scope.getSymbol(d.tname)
|
|
18 else:
|
|
19 msg = 'Cannot resolve name {0}'.format(d.tname)
|
152
|
20 self.diag.error(msg, d.loc)
|
150
|
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 print(sym.condition)
|
|
36 self.check(sym.truestatement)
|
|
37 self.check(sym.falsestatement)
|
|
38 elif type(sym) is VariableUse:
|
|
39 if type(sym.target) is Designator:
|
|
40 sym.target = self.resolveDesignator(sym.target)
|
|
41 elif type(sym) is Assignment:
|
|
42 self.check(sym.lval)
|
|
43 self.check(sym.rval)
|
|
44 elif type(sym) is ReturnStatement:
|
|
45 self.check(sym.expr)
|
|
46 elif type(sym) is Constant:
|
|
47 if type(sym.value) is int:
|
|
48 sym.typ = topScope.getSymbol('int')
|
|
49 elif type(sym) is FunctionType:
|
|
50 if type(sym.returntype) is Designator:
|
|
51 sym.returntype = self.resolveDesignator(sym.returntype)
|
|
52 self.check(sym.returntype)
|
|
53 elif type(sym) is Binop:
|
|
54 self.check(sym.a)
|
|
55 self.check(sym.b)
|
|
56 if type(sym.a) is Constant and type(sym.b) is Constant:
|
|
57 # Possibly fold expression
|
|
58 pass
|
|
59
|