Mercurial > lcfOS
comparison python/c3/typecheck.py @ 228:7f18ed9b6b7e
Removal of emptystatement class
author | Windel Bouwman |
---|---|
date | Sat, 13 Jul 2013 11:12:24 +0200 |
parents | 82dfe6a32717 |
children | 88a1e0baef65 |
comparison
equal
deleted
inserted
replaced
227:82dfe6a32717 | 228:7f18ed9b6b7e |
---|---|
1 from .astnodes import * | 1 from .astnodes import * |
2 from .scope import * | 2 from .scope import * |
3 from .visitor import Visitor | 3 from .visitor import Visitor |
4 | 4 |
5 def equalTypes(a, b): | 5 def equalTypes(a, b): |
6 """ Compare types a and b for equality. Not equal until proven otherwise. """ | 6 """ |
7 Compare types a and b for equality. | |
8 Not equal until proven otherwise. | |
9 """ | |
7 # Recurse into named types: | 10 # Recurse into named types: |
8 if type(a) is DefinedType: | 11 if type(a) is DefinedType: |
9 return equalTypes(a.typ, b) | 12 return equalTypes(a.typ, b) |
10 if type(b) is DefinedType: | 13 if type(b) is DefinedType: |
11 return equalTypes(a, b.typ) | 14 return equalTypes(a, b.typ) |
36 class TypeChecker: | 39 class TypeChecker: |
37 def __init__(self, diag): | 40 def __init__(self, diag): |
38 self.diag = diag | 41 self.diag = diag |
39 | 42 |
40 def error(self, msg, loc): | 43 def error(self, msg, loc): |
41 """ Wrapper that registers the message and marks the result invalid """ | 44 """ |
45 Wrapper that registers the message and marks the result invalid | |
46 """ | |
42 self.diag.error(msg, loc) | 47 self.diag.error(msg, loc) |
43 self.ok = False | 48 self.ok = False |
44 | 49 |
45 def checkPackage(self, pkg): | 50 def checkPackage(self, pkg): |
46 self.ok = True | 51 self.ok = True |
60 #if sym.rval.lvalue: | 65 #if sym.rval.lvalue: |
61 # self.error('Right hand side must be an rvalue', sym.rval.loc) | 66 # self.error('Right hand side must be an rvalue', sym.rval.loc) |
62 elif type(sym) is ReturnStatement: | 67 elif type(sym) is ReturnStatement: |
63 pass | 68 pass |
64 elif type(sym) is FunctionCall: | 69 elif type(sym) is FunctionCall: |
65 if sym.proc: | |
66 # Check arguments: | 70 # Check arguments: |
67 ngiv = len(sym.args) | 71 ngiv = len(sym.args) |
68 ptypes = sym.proc.typ.parametertypes | 72 ptypes = sym.proc.typ.parametertypes |
69 nreq = len(ptypes) | 73 nreq = len(ptypes) |
70 if ngiv != nreq: | 74 if ngiv != nreq: |
73 for a, at in zip(sym.args, ptypes): | 77 for a, at in zip(sym.args, ptypes): |
74 if not equalTypes(a.typ, at): | 78 if not equalTypes(a.typ, at): |
75 self.error('Got {0}, expected {1}'.format(a.typ, at), a.loc) | 79 self.error('Got {0}, expected {1}'.format(a.typ, at), a.loc) |
76 # determine return type: | 80 # determine return type: |
77 sym.typ = sym.proc.typ.returntype | 81 sym.typ = sym.proc.typ.returntype |
78 else: | |
79 sym.typ = intType | |
80 elif type(sym) is VariableUse: | 82 elif type(sym) is VariableUse: |
81 sym.lvalue = True | 83 sym.lvalue = True |
82 if type(sym.target) is Variable: | 84 if type(sym.target) is Variable: |
83 sym.typ = sym.target.typ | 85 sym.typ = sym.target.typ |
84 else: | 86 else: |
169 else: | 171 else: |
170 self.error('Cannot cast {} to {}'.format(sym.a.typ, sym.to_type)) | 172 self.error('Cannot cast {} to {}'.format(sym.a.typ, sym.to_type)) |
171 elif type(sym) is Constant: | 173 elif type(sym) is Constant: |
172 if not equalTypes(sym.typ, sym.value.typ): | 174 if not equalTypes(sym.typ, sym.value.typ): |
173 self.error('Cannot assign {0} to {1}'.format(sym.value.typ, sym.typ), sym.loc) | 175 self.error('Cannot assign {0} to {1}'.format(sym.value.typ, sym.typ), sym.loc) |
174 elif type(sym) in [EmptyStatement, CompoundStatement, Package, Function, FunctionType, ExpressionStatement, DefinedType]: | 176 elif type(sym) in [CompoundStatement, Package, Function, FunctionType, ExpressionStatement, DefinedType]: |
175 pass | 177 pass |
176 else: | 178 else: |
177 raise Exception('Unknown type check {0}'.format(sym)) | 179 raise Exception('Unknown type check {0}'.format(sym)) |
178 | 180 |