Mercurial > lcfOS
comparison python/c3/typecheck.py @ 220:3f6c30a5d234
Major change in expression parsing to enable pointers and structs
author | Windel Bouwman |
---|---|
date | Sat, 06 Jul 2013 21:32:20 +0200 |
parents | c1ccb1cb4cef |
children | 848c4b15fd0b |
comparison
equal
deleted
inserted
replaced
219:1fa3e0050b49 | 220:3f6c30a5d234 |
---|---|
5 def equalTypes(a, b): | 5 def equalTypes(a, b): |
6 """ Compare types a and b for equality. Not equal until proven otherwise. """ | 6 """ Compare types a and b for equality. Not equal until proven otherwise. """ |
7 if type(a) is type(b): | 7 if type(a) is type(b): |
8 if type(a) is BaseType: | 8 if type(a) is BaseType: |
9 return a.name == b.name | 9 return a.name == b.name |
10 elif type(a) is PointerType: | |
11 return equalTypes(a.ptype, b.ptype) | |
10 return False | 12 return False |
11 | 13 |
12 class TypeChecker: | 14 class TypeChecker: |
13 def __init__(self, diag): | 15 def __init__(self, diag): |
14 self.diag = diag | 16 self.diag = diag |
15 def error(self, msg, loc): | 17 |
18 def error(self, msg, loc): | |
16 """ Wrapper that registers the message and marks the result invalid """ | 19 """ Wrapper that registers the message and marks the result invalid """ |
17 self.diag.error(msg, loc) | 20 self.diag.error(msg, loc) |
18 self.ok = False | 21 self.ok = False |
19 def checkPackage(self, pkg): | 22 |
23 def checkPackage(self, pkg): | |
20 self.ok = True | 24 self.ok = True |
21 visitor = Visitor() | 25 visitor = Visitor() |
22 visitor.visit(pkg, f_post=self.check2) | 26 visitor.visit(pkg, f_post=self.check2) |
23 return self.ok | 27 return self.ok |
24 def check2(self, sym): | 28 |
25 if type(sym) is Function: | 29 def check2(self, sym): |
26 pass | 30 if type(sym) in [IfStatement, WhileStatement]: |
27 elif type(sym) in [IfStatement, WhileStatement]: | |
28 if not equalTypes(sym.condition.typ, boolType): | 31 if not equalTypes(sym.condition.typ, boolType): |
29 self.error('Condition must be of type {0}'.format(boolType), sym.condition.loc) | 32 self.error('Condition must be of type {0}'.format(boolType), sym.condition.loc) |
30 elif type(sym) is Assignment: | 33 elif type(sym) is Assignment: |
31 if not equalTypes(sym.lval.typ, sym.rval.typ): | 34 if type(sym.lval.typ) is PointerType and sym.rval.typ == intType: |
35 print('special case, int to pointer is ok for now') | |
36 # TODO: add cast instruction? | |
37 elif not equalTypes(sym.lval.typ, sym.rval.typ): | |
32 self.error('Cannot assign {0} to {1}'.format(sym.rval.typ, sym.lval.typ), sym.loc) | 38 self.error('Cannot assign {0} to {1}'.format(sym.rval.typ, sym.lval.typ), sym.loc) |
33 elif type(sym) is ReturnStatement: | 39 elif type(sym) is ReturnStatement: |
34 pass | 40 pass |
35 elif type(sym) is FunctionCall: | 41 elif type(sym) is FunctionCall: |
36 if sym.proc: | 42 if sym.proc: |
60 sym.typ = doubleType | 66 sym.typ = doubleType |
61 elif type(sym.val) is bool: | 67 elif type(sym.val) is bool: |
62 sym.typ = boolType | 68 sym.typ = boolType |
63 else: | 69 else: |
64 self.error('Unknown literal type', sym.loc) | 70 self.error('Unknown literal type', sym.loc) |
71 elif type(sym) is Unop: | |
72 if sym.op == '&': | |
73 sym.typ = PointerType(sym.a.typ) | |
74 elif sym.op == '*': | |
75 # pointer deref | |
76 if type(sym.a.typ) is PointerType: | |
77 sym.typ = sym.a.typ.ptype | |
78 else: | |
79 self.error('Cannot dereference non-pointer type {}'.format(sym.a.typ), sym.loc) | |
80 else: | |
81 print('unknown unop', sym.op) | |
65 elif type(sym) is Binop: | 82 elif type(sym) is Binop: |
66 if sym.op in ['+', '-', '*', '/']: | 83 if sym.op in ['+', '-', '*', '/']: |
67 if equalTypes(sym.a.typ, sym.b.typ): | 84 if equalTypes(sym.a.typ, sym.b.typ): |
68 if equalTypes(sym.a.typ, intType): | 85 if equalTypes(sym.a.typ, intType): |
69 sym.typ = sym.a.typ | 86 sym.typ = sym.a.typ |
92 # TODO | 109 # TODO |
93 pass | 110 pass |
94 elif type(sym) is Constant: | 111 elif type(sym) is Constant: |
95 if not equalTypes(sym.typ, sym.value.typ): | 112 if not equalTypes(sym.typ, sym.value.typ): |
96 self.error('Cannot assign {0} to {1}'.format(sym.value.typ, sym.typ), sym.loc) | 113 self.error('Cannot assign {0} to {1}'.format(sym.value.typ, sym.typ), sym.loc) |
97 | |
98 elif type(sym) in [EmptyStatement, CompoundStatement, Package, Function, FunctionType]: | 114 elif type(sym) in [EmptyStatement, CompoundStatement, Package, Function, FunctionType]: |
99 pass | 115 pass |
100 else: | 116 else: |
101 raise Exception('Unknown type check {0}'.format(sym)) | 117 raise Exception('Unknown type check {0}'.format(sym)) |
102 | 118 |