Mercurial > lcfOS
comparison python/c3/typecheck.py @ 166:da0087b82fbe
Improved type checking
author | Windel Bouwman |
---|---|
date | Fri, 22 Mar 2013 16:15:31 +0100 |
parents | 598d3888a11c |
children | 0b5b2ee6b435 |
comparison
equal
deleted
inserted
replaced
165:598d3888a11c | 166:da0087b82fbe |
---|---|
20 def check2(self, sym): | 20 def check2(self, sym): |
21 if type(sym) is Function: | 21 if type(sym) is Function: |
22 pass | 22 pass |
23 elif type(sym) in [IfStatement, WhileStatement]: | 23 elif type(sym) in [IfStatement, WhileStatement]: |
24 if not equalTypes(sym.condition.typ, boolType): | 24 if not equalTypes(sym.condition.typ, boolType): |
25 self.diag.error('Condition must be a boolean expression', sym.condition.loc) | 25 self.diag.error('Condition must be of type {0}'.format(boolType), sym.condition.loc) |
26 elif type(sym) is Assignment: | 26 elif type(sym) is Assignment: |
27 if not equalTypes(sym.lval.typ, sym.rval.typ): | 27 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) | 28 self.diag.error('Cannot assign {0} to {1}'.format(sym.rval.typ, sym.lval.typ), sym.loc) |
29 elif type(sym) is ReturnStatement: | 29 elif type(sym) is ReturnStatement: |
30 pass | 30 pass |
31 elif type(sym) is ProcedureCall: | 31 elif type(sym) is ProcedureCall: |
32 # Check arguments: | 32 # Check arguments: |
33 | 33 if sym.proc: |
34 pass | |
34 # determine return type: | 35 # determine return type: |
35 sym.typ = sym.proc.typ.returntype | 36 sym.typ = sym.proc.typ.returntype |
36 elif type(sym) is VariableUse: | 37 elif type(sym) is VariableUse: |
37 if sym.target: | 38 if sym.target: |
38 sym.typ = sym.target.typ | 39 sym.typ = sym.target.typ |
41 elif type(sym) is Literal: | 42 elif type(sym) is Literal: |
42 if type(sym.val) is int: | 43 if type(sym.val) is int: |
43 sym.typ = intType | 44 sym.typ = intType |
44 elif type(sym.val) is float: | 45 elif type(sym.val) is float: |
45 sym.typ = doubleType | 46 sym.typ = doubleType |
47 elif type(sym.val) is bool: | |
48 sym.typ = boolType | |
46 else: | 49 else: |
47 self.diag.error('Unknown literal type', sym.loc) | 50 self.diag.error('Unknown literal type', sym.loc) |
48 elif type(sym) is Binop: | 51 elif type(sym) is Binop: |
49 if sym.op in ['+', '-', '*', '/']: | 52 if sym.op in ['+', '-', '*', '/']: |
50 if equalTypes(sym.a.typ, sym.b.typ): | 53 if equalTypes(sym.a.typ, sym.b.typ): |
55 self.diag.error('Types unequal', sym.loc) | 58 self.diag.error('Types unequal', sym.loc) |
56 elif sym.op in ['>', '<']: | 59 elif sym.op in ['>', '<']: |
57 sym.typ = boolType | 60 sym.typ = boolType |
58 if not equalTypes(sym.a.typ, sym.b.typ): | 61 if not equalTypes(sym.a.typ, sym.b.typ): |
59 self.diag.error('Types unequal', sym.loc) | 62 self.diag.error('Types unequal', sym.loc) |
63 elif sym.op in ['or', 'and']: | |
64 sym.typ = boolType | |
65 if not equalTypes(sym.a.typ, boolType): | |
66 self.diag.error('Must be {0}'.format(boolType), sym.a.loc) | |
67 if not equalTypes(sym.b.typ, boolType): | |
68 self.diag.error('Must be {0}'.format(boolType), sym.b.loc) | |
60 else: | 69 else: |
61 sym.typ = voidType | 70 sym.typ = voidType |
62 print('unknown binop', sym.op) | 71 print('unknown binop', sym.op) |
63 elif type(sym) is Variable: | 72 elif type(sym) is Variable: |
64 # check initial value type: | 73 # check initial value type: |
65 # TODO | 74 # TODO |
66 pass | 75 pass |
67 elif type(sym) in [EmptyStatement, CompoundStatement, Package]: | 76 elif type(sym) is Constant: |
77 if not equalTypes(sym.typ, sym.value.typ): | |
78 self.diag.error('Cannot assign {0} to {1}'.format(sym.value.typ, sym.typ), sym.loc) | |
79 | |
80 elif type(sym) in [EmptyStatement, CompoundStatement, Package, Function]: | |
68 pass | 81 pass |
69 else: | 82 else: |
70 print('Unknown type check', sym) | 83 print('Unknown type check', sym) |
71 | 84 |