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 ppci.errors import CompilerException
|
|
8 from .scope import topScope
|
|
9
|
|
10 class TypeChecker:
|
|
11 def __init__(self, diag):
|
|
12 self.diag = diag
|
|
13 def err(self, msg, loc):
|
|
14 self.diag.diag(CompilerException(msg, loc))
|
|
15 def checkPackage(self, pkg):
|
|
16 for s in pkg.scope:
|
|
17 self.check(s)
|
|
18 def resolveDesignator(self, d):
|
|
19 if d.scope.hasSymbol(d.tname):
|
|
20 return d.scope.getSymbol(d.tname)
|
|
21 else:
|
|
22 msg = 'Cannot resolve name {0}'.format(d.tname)
|
|
23 self.err(msg, d.loc)
|
|
24 def check(self, sym):
|
|
25 if type(sym) is Variable:
|
|
26 if type(sym.typ) is Designator:
|
|
27 sym.typ = self.resolveDesignator(sym.typ)
|
|
28 elif type(sym) is Function:
|
|
29 for s in sym.scope:
|
|
30 self.check(s)
|
|
31 self.check(sym.typ)
|
|
32 self.check(sym.body)
|
|
33 elif type(sym) is CompoundStatement:
|
|
34 for s in sym.statements:
|
|
35 self.check(s)
|
|
36 elif type(sym) is IfStatement:
|
|
37 self.check(sym.condition)
|
|
38 print(sym.condition)
|
|
39 self.check(sym.truestatement)
|
|
40 self.check(sym.falsestatement)
|
|
41 elif type(sym) is VariableUse:
|
|
42 if type(sym.target) is Designator:
|
|
43 sym.target = self.resolveDesignator(sym.target)
|
|
44 elif type(sym) is Assignment:
|
|
45 self.check(sym.lval)
|
|
46 self.check(sym.rval)
|
|
47 elif type(sym) is ReturnStatement:
|
|
48 self.check(sym.expr)
|
|
49 elif type(sym) is Constant:
|
|
50 if type(sym.value) is int:
|
|
51 sym.typ = topScope.getSymbol('int')
|
|
52 elif type(sym) is FunctionType:
|
|
53 if type(sym.returntype) is Designator:
|
|
54 sym.returntype = self.resolveDesignator(sym.returntype)
|
|
55 self.check(sym.returntype)
|
|
56 elif type(sym) is Binop:
|
|
57 self.check(sym.a)
|
|
58 self.check(sym.b)
|
|
59 if type(sym.a) is Constant and type(sym.b) is Constant:
|
|
60 # Possibly fold expression
|
|
61 pass
|
|
62
|