Mercurial > lcfOS
comparison python/c3/typecheck.py @ 186:46d62dadd61b
Improved testsuite
author | Windel Bouwman |
---|---|
date | Sat, 25 May 2013 14:26:25 +0200 |
parents | 4348da5ca307 |
children | c1ccb1cb4cef |
comparison
equal
deleted
inserted
replaced
185:51a6440d6398 | 186:46d62dadd61b |
---|---|
11 | 11 |
12 class TypeChecker: | 12 class TypeChecker: |
13 def __init__(self, diag): | 13 def __init__(self, diag): |
14 self.diag = diag | 14 self.diag = diag |
15 self.visitor = Visitor(self.precheck, self.check2) | 15 self.visitor = Visitor(self.precheck, self.check2) |
16 def error(self, msg, loc): | |
17 """ Wrapper that registers the message and marks the result invalid """ | |
18 self.diag.error(msg, loc) | |
19 self.ok = False | |
16 def checkPackage(self, pkg): | 20 def checkPackage(self, pkg): |
17 self.visitor.visit(pkg) | 21 self.ok = True |
22 self.visitor.visit(pkg) | |
23 return self.ok | |
18 def precheck(self, sym): | 24 def precheck(self, sym): |
19 pass | 25 pass |
20 def check2(self, sym): | 26 def check2(self, sym): |
21 if type(sym) is Function: | 27 if type(sym) is Function: |
22 pass | 28 pass |
23 elif type(sym) in [IfStatement, WhileStatement]: | 29 elif type(sym) in [IfStatement, WhileStatement]: |
24 if not equalTypes(sym.condition.typ, boolType): | 30 if not equalTypes(sym.condition.typ, boolType): |
25 self.diag.error('Condition must be of type {0}'.format(boolType), sym.condition.loc) | 31 self.error('Condition must be of type {0}'.format(boolType), sym.condition.loc) |
26 elif type(sym) is Assignment: | 32 elif type(sym) is Assignment: |
27 if not equalTypes(sym.lval.typ, sym.rval.typ): | 33 if not equalTypes(sym.lval.typ, sym.rval.typ): |
28 self.diag.error('Cannot assign {0} to {1}'.format(sym.rval.typ, sym.lval.typ), sym.loc) | 34 self.error('Cannot assign {0} to {1}'.format(sym.rval.typ, sym.lval.typ), sym.loc) |
29 elif type(sym) is ReturnStatement: | 35 elif type(sym) is ReturnStatement: |
30 pass | 36 pass |
31 elif type(sym) is FunctionCall: | 37 elif type(sym) is FunctionCall: |
32 if sym.proc: | 38 if sym.proc: |
33 # Check arguments: | 39 # Check arguments: |
34 ngiv = len(sym.args) | 40 ngiv = len(sym.args) |
35 ptypes = sym.proc.typ.parametertypes | 41 ptypes = sym.proc.typ.parametertypes |
36 nreq = len(ptypes) | 42 nreq = len(ptypes) |
37 if ngiv != nreq: | 43 if ngiv != nreq: |
38 self.diag.error('Function {2}: {0} arguments required, {1} given'.format(nreq, ngiv, sym.proc.name), sym.loc) | 44 self.error('Function {2}: {0} arguments required, {1} given'.format(nreq, ngiv, sym.proc.name), sym.loc) |
39 else: | 45 else: |
40 for a, at in zip(sym.args, ptypes): | 46 for a, at in zip(sym.args, ptypes): |
41 if not equalTypes(a.typ, at): | 47 if not equalTypes(a.typ, at): |
42 self.diag.error('Got {0}, expected {1}'.format(a.typ, at), a.loc) | 48 self.error('Got {0}, expected {1}'.format(a.typ, at), a.loc) |
43 # determine return type: | 49 # determine return type: |
44 sym.typ = sym.proc.typ.returntype | 50 sym.typ = sym.proc.typ.returntype |
45 else: | 51 else: |
46 sym.typ = intType | 52 sym.typ = intType |
47 elif type(sym) is VariableUse: | 53 elif type(sym) is VariableUse: |
55 elif type(sym.val) is float: | 61 elif type(sym.val) is float: |
56 sym.typ = doubleType | 62 sym.typ = doubleType |
57 elif type(sym.val) is bool: | 63 elif type(sym.val) is bool: |
58 sym.typ = boolType | 64 sym.typ = boolType |
59 else: | 65 else: |
60 self.diag.error('Unknown literal type', sym.loc) | 66 self.error('Unknown literal type', sym.loc) |
61 elif type(sym) is Binop: | 67 elif type(sym) is Binop: |
62 if sym.op in ['+', '-', '*', '/']: | 68 if sym.op in ['+', '-', '*', '/']: |
63 if equalTypes(sym.a.typ, sym.b.typ): | 69 if equalTypes(sym.a.typ, sym.b.typ): |
64 if equalTypes(sym.a.typ, intType): | 70 if equalTypes(sym.a.typ, intType): |
65 sym.typ = sym.a.typ | 71 sym.typ = sym.a.typ |
66 else: | 72 else: |
67 self.diag.error('Can only add integers', sym.loc) | 73 self.error('Can only add integers', sym.loc) |
68 sym.typ = intType | 74 sym.typ = intType |
69 else: | 75 else: |
70 # assume void here? TODO: throw exception! | 76 # assume void here? TODO: throw exception! |
71 sym.typ = intType | 77 sym.typ = intType |
72 self.diag.error('Types unequal', sym.loc) | 78 self.error('Types unequal', sym.loc) |
73 elif sym.op in ['>', '<', '==', '<=', '>=']: | 79 elif sym.op in ['>', '<', '==', '<=', '>=']: |
74 sym.typ = boolType | 80 sym.typ = boolType |
75 if not equalTypes(sym.a.typ, sym.b.typ): | 81 if not equalTypes(sym.a.typ, sym.b.typ): |
76 self.diag.error('Types unequal', sym.loc) | 82 self.error('Types unequal', sym.loc) |
77 elif sym.op in ['or', 'and']: | 83 elif sym.op in ['or', 'and']: |
78 sym.typ = boolType | 84 sym.typ = boolType |
79 if not equalTypes(sym.a.typ, boolType): | 85 if not equalTypes(sym.a.typ, boolType): |
80 self.diag.error('Must be {0}'.format(boolType), sym.a.loc) | 86 self.error('Must be {0}'.format(boolType), sym.a.loc) |
81 if not equalTypes(sym.b.typ, boolType): | 87 if not equalTypes(sym.b.typ, boolType): |
82 self.diag.error('Must be {0}'.format(boolType), sym.b.loc) | 88 self.error('Must be {0}'.format(boolType), sym.b.loc) |
83 else: | 89 else: |
84 sym.typ = voidType | 90 sym.typ = voidType |
85 print('unknown binop', sym.op) | 91 print('unknown binop', sym.op) |
86 elif type(sym) is Variable: | 92 elif type(sym) is Variable: |
87 # check initial value type: | 93 # check initial value type: |
88 # TODO | 94 # TODO |
89 pass | 95 pass |
90 elif type(sym) is Constant: | 96 elif type(sym) is Constant: |
91 if not equalTypes(sym.typ, sym.value.typ): | 97 if not equalTypes(sym.typ, sym.value.typ): |
92 self.diag.error('Cannot assign {0} to {1}'.format(sym.value.typ, sym.typ), sym.loc) | 98 self.error('Cannot assign {0} to {1}'.format(sym.value.typ, sym.typ), sym.loc) |
93 | 99 |
94 elif type(sym) in [EmptyStatement, CompoundStatement, Package, Function, FunctionType]: | 100 elif type(sym) in [EmptyStatement, CompoundStatement, Package, Function, FunctionType]: |
95 pass | 101 pass |
96 else: | 102 else: |
97 print('Unknown type check', sym) | 103 raise Exception('Unknown type check {0}'.format(sym)) |
98 | 104 |