comparison python/ppci/c3/codegenerator.py @ 308:2e7f55319858

Merged analyse into codegenerator
author Windel Bouwman
date Fri, 13 Dec 2013 11:53:29 +0100
parents e609d5296ee9
children ff665880a6b0
comparison
equal deleted inserted replaced
307:e609d5296ee9 308:2e7f55319858
1 import logging 1 import logging
2 from .. import ir 2 from .. import ir
3 from .. import irutils 3 from .. import irutils
4 from .astnodes import Symbol, Package, Variable, Function 4 from . import astnodes as ast
5 from .astnodes import Statement, Empty, Compound, If, While, Assignment
6 from .astnodes import ExpressionStatement, Return
7 from .astnodes import Expression, Binop, Unop, Identifier, Deref, Member
8 from .astnodes import Expression, FunctionCall, Literal, TypeCast
9 from .astnodes import Type, DefinedType, BaseType, PointerType, StructureType
10
11 from ppci import CompilerError
12 5
13 6
14 class SemanticError(Exception): 7 class SemanticError(Exception):
8 """ Error thrown when a semantic issue is observed """
15 def __init__(self, msg, loc): 9 def __init__(self, msg, loc):
10 super().__init__()
16 self.msg = msg 11 self.msg = msg
17 self.loc = loc 12 self.loc = loc
18 13
19 14
20 class CodeGenerator(irutils.Builder): 15 class CodeGenerator(irutils.Builder):
31 def __init__(self, diag): 26 def __init__(self, diag):
32 self.logger = logging.getLogger('c3cgen') 27 self.logger = logging.getLogger('c3cgen')
33 self.diag = diag 28 self.diag = diag
34 29
35 def gencode(self, pkg): 30 def gencode(self, pkg):
31 """ Generate code for a single module """
36 self.prepare() 32 self.prepare()
37 assert type(pkg) is Package 33 assert type(pkg) is ast.Package
38 self.pkg = pkg 34 self.pkg = pkg
39 self.intType = pkg.scope['int'] 35 self.intType = pkg.scope['int']
40 self.boolType = pkg.scope['bool'] 36 self.boolType = pkg.scope['bool']
41 self.logger.info('Generating ir-code for {}'.format(pkg.name)) 37 self.logger.info('Generating ir-code for {}'.format(pkg.name))
42 self.varMap = {} # Maps variables to storage locations. 38 self.varMap = {} # Maps variables to storage locations.
43 self.funcMap = {} 39 self.funcMap = {}
44 self.m = ir.Module(pkg.name) 40 self.m = ir.Module(pkg.name)
45 self.genModule(pkg)
46 return self.m
47
48 def error(self, msg, loc=None):
49 self.pkg.ok = False
50 self.diag.error(msg, loc)
51
52 # inner helpers:
53 def genModule(self, pkg):
54 # Take care of forward declarations:
55 try: 41 try:
56 for s in pkg.innerScope.Functions: 42 for s in pkg.innerScope.Functions:
57 f = self.newFunction(s.name) 43 f = self.newFunction(s.name)
58 self.funcMap[s] = f 44 self.funcMap[s] = f
59 for v in pkg.innerScope.Variables: 45 for v in pkg.innerScope.Variables:
60 self.varMap[v] = self.newTemp() 46 self.varMap[v] = self.newTemp()
61 for s in pkg.innerScope.Functions: 47 for s in pkg.innerScope.Functions:
62 self.genFunction(s) 48 self.gen_function(s)
63 except SemanticError as e: 49 except SemanticError as e:
64 self.error(e.msg, e.loc) 50 self.error(e.msg, e.loc)
51 return self.m
52
53 def error(self, msg, loc=None):
54 self.pkg.ok = False
55 self.diag.error(msg, loc)
65 56
66 def checkType(self, t): 57 def checkType(self, t):
67 """ Verify the type is correct """ 58 """ Verify the type is correct """
68 t = self.theType(t) 59 t = self.theType(t)
69 60
70 def genFunction(self, fn): 61 def gen_function(self, fn):
71 # TODO: handle arguments 62 # TODO: handle arguments
72 f = self.funcMap[fn] 63 f = self.funcMap[fn]
73 f.return_value = self.newTemp() 64 f.return_value = self.newTemp()
74 self.setFunction(f) 65 self.setFunction(f)
75 l2 = self.newBlock() 66 l2 = self.newBlock()
79 70
80 for sym in fn.innerScope: 71 for sym in fn.innerScope:
81 # TODO: handle parameters different 72 # TODO: handle parameters different
82 if sym.isParameter: 73 if sym.isParameter:
83 self.checkType(sym.typ) 74 self.checkType(sym.typ)
84 v = ir.Parameter(sym.name) 75 variable = ir.Parameter(sym.name)
85 f.addParameter(v) 76 f.addParameter(variable)
86 elif sym.isLocal: 77 elif sym.isLocal:
87 self.checkType(sym.typ) 78 self.checkType(sym.typ)
88 v = ir.LocalVariable(sym.name) 79 variable = ir.LocalVariable(sym.name)
89 f.addLocal(v) 80 f.addLocal(variable)
90 elif isinstance(sym, Variable): 81 elif isinstance(sym, ast.Variable):
91 self.checkType(sym.typ) 82 self.checkType(sym.typ)
92 v = ir.LocalVariable(sym.name) 83 variable = ir.LocalVariable(sym.name)
93 f.addLocal(v) 84 f.addLocal(variable)
94 else: 85 else:
95 #v = self.newTemp()
96 raise NotImplementedError('{}'.format(sym)) 86 raise NotImplementedError('{}'.format(sym))
97 self.varMap[sym] = v 87 self.varMap[sym] = variable
98 88
99 self.genCode(fn.body) 89 self.genCode(fn.body)
100 # Set the default return value to zero:
101 # TBD: this may not be required?
102 self.emit(ir.Move(f.return_value, ir.Const(0))) 90 self.emit(ir.Move(f.return_value, ir.Const(0)))
103 self.emit(ir.Jump(f.epiloog)) 91 self.emit(ir.Jump(f.epiloog))
104 self.setFunction(None) 92 self.setFunction(None)
105 93
106 def genCode(self, code): 94 def genCode(self, code):
95 """ Wrapper around gen_stmt to catch errors """
107 try: 96 try:
108 self.genStmt(code) 97 self.gen_stmt(code)
109 except SemanticError as e: 98 except SemanticError as e:
110 self.error(e.msg, e.loc) 99 self.error(e.msg, e.loc)
111 100
112 def genStmt(self, code): 101 def gen_stmt(self, code):
113 assert isinstance(code, Statement) 102 """ Generate code for a statement """
103 assert isinstance(code, ast.Statement)
114 self.setLoc(code.loc) 104 self.setLoc(code.loc)
115 if type(code) is Compound: 105 if type(code) is ast.Compound:
116 for s in code.statements: 106 for s in code.statements:
117 self.genCode(s) 107 self.genCode(s)
118 elif type(code) is Empty: 108 elif type(code) is ast.Empty:
119 pass 109 pass
120 elif type(code) is Assignment: 110 elif type(code) is ast.Assignment:
121 lval = self.genExprCode(code.lval) 111 lval = self.genExprCode(code.lval)
122 rval = self.genExprCode(code.rval) 112 rval = self.genExprCode(code.rval)
123 if not self.equalTypes(code.lval.typ, code.rval.typ): 113 if not self.equalTypes(code.lval.typ, code.rval.typ):
124 msg = 'Cannot assign {} to {}'.format(code.lval.typ, code.rval.typ) 114 msg = 'Cannot assign {} to {}'.format(code.lval.typ, code.rval.typ)
125 raise SemanticError(msg, code.loc) 115 raise SemanticError(msg, code.loc)
126 if not code.lval.lvalue: 116 if not code.lval.lvalue:
127 raise SemanticError('No valid lvalue {}'.format(code.lval), code.lval.loc) 117 raise SemanticError('No valid lvalue {}'.format(code.lval), code.lval.loc)
128 self.emit(ir.Move(lval, rval)) 118 self.emit(ir.Move(lval, rval))
129 elif type(code) is ExpressionStatement: 119 elif type(code) is ast.ExpressionStatement:
130 self.emit(ir.Exp(self.genExprCode(code.ex))) 120 self.emit(ir.Exp(self.genExprCode(code.ex)))
131 elif type(code) is If: 121 elif type(code) is ast.If:
132 bbtrue = self.newBlock() 122 bbtrue = self.newBlock()
133 bbfalse = self.newBlock() 123 bbfalse = self.newBlock()
134 te = self.newBlock() 124 te = self.newBlock()
135 self.genCondCode(code.condition, bbtrue, bbfalse) 125 self.gen_cond_code(code.condition, bbtrue, bbfalse)
136 self.setBlock(bbtrue) 126 self.setBlock(bbtrue)
137 self.genCode(code.truestatement) 127 self.genCode(code.truestatement)
138 self.emit(ir.Jump(te)) 128 self.emit(ir.Jump(te))
139 self.setBlock(bbfalse) 129 self.setBlock(bbfalse)
140 self.genCode(code.falsestatement) 130 self.genCode(code.falsestatement)
141 self.emit(ir.Jump(te)) 131 self.emit(ir.Jump(te))
142 self.setBlock(te) 132 self.setBlock(te)
143 elif type(code) is Return: 133 elif type(code) is ast.Return:
144 re = self.genExprCode(code.expr) 134 re = self.genExprCode(code.expr)
145 self.emit(ir.Move(self.fn.return_value, re)) 135 self.emit(ir.Move(self.fn.return_value, re))
146 self.emit(ir.Jump(self.fn.epiloog)) 136 self.emit(ir.Jump(self.fn.epiloog))
147 b = self.newBlock() 137 b = self.newBlock()
148 self.setBlock(b) 138 self.setBlock(b)
149 elif type(code) is While: 139 elif type(code) is ast.While:
150 bbdo = self.newBlock() 140 bbdo = self.newBlock()
151 bbtest = self.newBlock() 141 bbtest = self.newBlock()
152 te = self.newBlock() 142 te = self.newBlock()
153 self.emit(ir.Jump(bbtest)) 143 self.emit(ir.Jump(bbtest))
154 self.setBlock(bbtest) 144 self.setBlock(bbtest)
155 self.genCondCode(code.condition, bbdo, te) 145 self.gen_cond_code(code.condition, bbdo, te)
156 self.setBlock(bbdo) 146 self.setBlock(bbdo)
157 self.genCode(code.statement) 147 self.genCode(code.statement)
158 self.emit(ir.Jump(bbtest)) 148 self.emit(ir.Jump(bbtest))
159 self.setBlock(te) 149 self.setBlock(te)
160 else: 150 else:
161 raise NotImplementedError('Unknown stmt {}'.format(code)) 151 raise NotImplementedError('Unknown stmt {}'.format(code))
162 152
163 def genCondCode(self, expr, bbtrue, bbfalse): 153 def gen_cond_code(self, expr, bbtrue, bbfalse):
164 # Implement sequential logical operators 154 """ Generate conditional logic.
165 if type(expr) is Binop: 155 Implement sequential logical operators. """
156 if type(expr) is ast.Binop:
166 if expr.op == 'or': 157 if expr.op == 'or':
167 l2 = self.newBlock() 158 l2 = self.newBlock()
168 self.genCondCode(expr.a, bbtrue, l2) 159 self.gen_cond_code(expr.a, bbtrue, l2)
169 if not equalTypes(expr.a.typ, self.boolType): 160 if not self.equalTypes(expr.a.typ, self.boolType):
170 raise SemanticError('Must be boolean', expr.a.loc) 161 raise SemanticError('Must be boolean', expr.a.loc)
171 self.setBlock(l2) 162 self.setBlock(l2)
172 self.genCondCode(expr.b, bbtrue, bbfalse) 163 self.gen_cond_code(expr.b, bbtrue, bbfalse)
173 if not equalTypes(expr.b.typ, self.boolType): 164 if not self.equalTypes(expr.b.typ, self.boolType):
174 raise SemanticError('Must be boolean', expr.b.loc) 165 raise SemanticError('Must be boolean', expr.b.loc)
175 elif expr.op == 'and': 166 elif expr.op == 'and':
176 l2 = self.newBlock() 167 l2 = self.newBlock()
177 self.genCondCode(expr.a, l2, bbfalse) 168 self.gen_cond_code(expr.a, l2, bbfalse)
178 if not equalTypes(expr.a.typ, self.boolType): 169 if not self.equalTypes(expr.a.typ, self.boolType):
179 self.error('Must be boolean', expr.a.loc) 170 self.error('Must be boolean', expr.a.loc)
180 self.setBlock(l2) 171 self.setBlock(l2)
181 self.genCondCode(expr.b, bbtrue, bbfalse) 172 self.gen_cond_code(expr.b, bbtrue, bbfalse)
182 if not equalTypes(expr.b.typ, self.boolType): 173 if not self.equalTypes(expr.b.typ, self.boolType):
183 raise SemanticError('Must be boolean', expr.b.loc) 174 raise SemanticError('Must be boolean', expr.b.loc)
184 elif expr.op in ['==', '>', '<', '!=', '<=', '>=']: 175 elif expr.op in ['==', '>', '<', '!=', '<=', '>=']:
185 ta = self.genExprCode(expr.a) 176 ta = self.genExprCode(expr.a)
186 tb = self.genExprCode(expr.b) 177 tb = self.genExprCode(expr.b)
187 if not self.equalTypes(expr.a.typ, expr.b.typ): 178 if not self.equalTypes(expr.a.typ, expr.b.typ):
189 .format(expr.a.typ, expr.b.typ), expr.loc) 180 .format(expr.a.typ, expr.b.typ), expr.loc)
190 self.emit(ir.CJump(ta, expr.op, tb, bbtrue, bbfalse)) 181 self.emit(ir.CJump(ta, expr.op, tb, bbtrue, bbfalse))
191 else: 182 else:
192 raise NotImplementedError('Unknown condition {}'.format(expr)) 183 raise NotImplementedError('Unknown condition {}'.format(expr))
193 expr.typ = self.boolType 184 expr.typ = self.boolType
194 elif type(expr) is Literal: 185 elif type(expr) is ast.Literal:
186 self.genExprCode(expr)
195 if expr.val: 187 if expr.val:
196 self.emit(ir.Jump(bbtrue)) 188 self.emit(ir.Jump(bbtrue))
197 else: 189 else:
198 self.emit(ir.Jump(bbfalse)) 190 self.emit(ir.Jump(bbfalse))
199 expr.typ = self.boolType
200 else: 191 else:
201 raise NotImplementedError('Unknown cond {}'.format(expr)) 192 raise NotImplementedError('Unknown cond {}'.format(expr))
202 if not self.equalTypes(expr.typ, self.boolType): 193 if not self.equalTypes(expr.typ, self.boolType):
203 self.error('Condition must be boolean', expr.loc) 194 self.error('Condition must be boolean', expr.loc)
204 195
205 def genExprCode(self, expr): 196 def genExprCode(self, expr):
206 assert isinstance(expr, Expression) 197 """ Generate code for an expression. Return the generated ir-value """
207 if type(expr) is Binop: 198 assert isinstance(expr, ast.Expression)
199 if type(expr) is ast.Binop:
208 expr.lvalue = False 200 expr.lvalue = False
209 if expr.op in ['+', '-', '*', '/', '<<', '>>', '|', '&']: 201 if expr.op in ['+', '-', '*', '/', '<<', '>>', '|', '&']:
210 ra = self.genExprCode(expr.a) 202 ra = self.genExprCode(expr.a)
211 rb = self.genExprCode(expr.b) 203 rb = self.genExprCode(expr.b)
212 if self.equalTypes(expr.a.typ, self.intType) and \ 204 if self.equalTypes(expr.a.typ, self.intType) and \
213 self.equalTypes(expr.b.typ, self.intType): 205 self.equalTypes(expr.b.typ, self.intType):
214 expr.typ = expr.a.typ 206 expr.typ = expr.a.typ
215 else: 207 else:
216 # assume void here? TODO: throw exception!
217 raise SemanticError('Can only add integers', expr.loc) 208 raise SemanticError('Can only add integers', expr.loc)
218 else: 209 else:
219 raise NotImplementedError("Cannot use equality as expressions") 210 raise NotImplementedError("Cannot use equality as expressions")
220 return ir.Binop(ra, expr.op, rb) 211 return ir.Binop(ra, expr.op, rb)
221 elif type(expr) is Unop: 212 elif type(expr) is ast.Unop:
222 if expr.op == '&': 213 if expr.op == '&':
223 ra = self.genExprCode(expr.a) 214 ra = self.genExprCode(expr.a)
224 expr.typ = PointerType(expr.a.typ) 215 expr.typ = ast.PointerType(expr.a.typ)
225 if not expr.a.lvalue: 216 if not expr.a.lvalue:
226 raise SemanticError('No valid lvalue', expr.a.loc) 217 raise SemanticError('No valid lvalue', expr.a.loc)
227 expr.lvalue = False 218 expr.lvalue = False
228 assert type(ra) is ir.Mem 219 assert type(ra) is ir.Mem
229 return ra.e 220 return ra.e
230 else: 221 else:
231 raise NotImplementedError('Unknown unop {0}'.format(expr.op)) 222 raise NotImplementedError('Unknown unop {0}'.format(expr.op))
232 elif type(expr) is Identifier: 223 elif type(expr) is ast.Identifier:
233 # Generate code for this identifier. 224 # Generate code for this identifier.
234 expr.lvalue = True 225 expr.lvalue = True
235 tg = self.resolveSymbol(expr) 226 tg = self.resolveSymbol(expr)
236 expr.kind = type(tg) 227 expr.kind = type(tg)
237 expr.typ = tg.typ 228 expr.typ = tg.typ
238 # This returns the dereferenced variable. 229 # This returns the dereferenced variable.
239 if type(tg) is Variable: 230 if isinstance(tg, ast.Variable):
240 # TODO: now parameters are handled different. Not nice?
241 return ir.Mem(self.varMap[tg]) 231 return ir.Mem(self.varMap[tg])
242 else: 232 else:
243 return ir.Mem(self.varMap[tg]) 233 raise NotImplementedError(str(tg))
244 elif type(expr) is Deref: 234 elif type(expr) is ast.Deref:
245 # dereference pointer type: 235 # dereference pointer type:
246 addr = self.genExprCode(expr.ptr) 236 addr = self.genExprCode(expr.ptr)
247 ptr_typ = self.theType(expr.ptr.typ) 237 ptr_typ = self.theType(expr.ptr.typ)
248 expr.lvalue = True 238 expr.lvalue = True
249 if type(ptr_typ) is PointerType: 239 if type(ptr_typ) is ast.PointerType:
250 expr.typ = ptr_typ.ptype 240 expr.typ = ptr_typ.ptype
251 return ir.Mem(addr) 241 return ir.Mem(addr)
252 else: 242 else:
253 raise SemanticError('Cannot deref non-pointer', expr.loc) 243 raise SemanticError('Cannot deref non-pointer', expr.loc)
254 expr.typ = self.intType 244 elif type(expr) is ast.Member:
255 return ir.Mem(ir.Const(0))
256 elif type(expr) is Member:
257 base = self.genExprCode(expr.base) 245 base = self.genExprCode(expr.base)
258 expr.lvalue = expr.base.lvalue 246 expr.lvalue = expr.base.lvalue
259 basetype = self.theType(expr.base.typ) 247 basetype = self.theType(expr.base.typ)
260 if type(basetype) is StructureType: 248 if type(basetype) is ast.StructureType:
261 if basetype.hasField(expr.field): 249 if basetype.hasField(expr.field):
262 expr.typ = basetype.fieldType(expr.field) 250 expr.typ = basetype.fieldType(expr.field)
263 else: 251 else:
264 raise SemanticError('{} does not contain field {}' 252 raise SemanticError('{} does not contain field {}'
265 .format(basetype, expr.field), expr.loc) 253 .format(basetype, expr.field), expr.loc)
266 else: 254 else:
267 raise SemanticError('Cannot select field {} of non-structure type {}' 255 raise SemanticError('Cannot select {} of non-structure type {}'
268 .format(sym.field, basetype), sym.loc) 256 .format(expr.field, basetype), expr.loc)
269 257
270 assert type(base) is ir.Mem, type(base) 258 assert type(base) is ir.Mem, type(base)
271 base = base.e
272 bt = self.theType(expr.base.typ) 259 bt = self.theType(expr.base.typ)
273 offset = ir.Const(bt.fieldOffset(expr.field)) 260 offset = ir.Const(bt.fieldOffset(expr.field))
274 return ir.Mem(ir.Add(base, offset)) 261 return ir.Mem(ir.Add(base.e, offset))
275 elif type(expr) is Literal: 262 elif type(expr) is ast.Literal:
276 expr.lvalue = False 263 expr.lvalue = False
277 typemap = {int: 'int', float: 'double', bool: 'bool'} 264 typemap = {int: 'int', float: 'double', bool: 'bool'}
278 if type(expr.val) in typemap: 265 if type(expr.val) in typemap:
279 expr.typ = self.pkg.scope[typemap[type(expr.val)]] 266 expr.typ = self.pkg.scope[typemap[type(expr.val)]]
280 else: 267 else:
281 raise SemanticError('Unknown literal type {}'.format(expr.val)) 268 raise SemanticError('Unknown literal type {}'.format(expr.val))
282 return ir.Const(expr.val) 269 return ir.Const(expr.val)
283 elif type(expr) is TypeCast: 270 elif type(expr) is ast.TypeCast:
284 # TODO: improve this mess: 271 return self.gen_type_cast(expr)
285 ar = self.genExprCode(expr.a) 272 elif type(expr) is ast.FunctionCall:
286 ft = self.theType(expr.a.typ) 273 return self.gen_function_call(expr)
287 tt = self.theType(expr.to_type)
288 if isinstance(ft, PointerType) and isinstance(tt, PointerType):
289 expr.typ = expr.to_type
290 return ar
291 elif type(ft) is BaseType and ft.name == 'int' and \
292 isinstance(tt, PointerType):
293 expr.typ = expr.to_type
294 return ar
295 else:
296 self.error('Cannot cast {} to {}'
297 .format(ft, tt), expr.loc)
298 expr.typ = self.intType
299 return ir.Const(0)
300 elif type(expr) is FunctionCall:
301 # Evaluate the arguments:
302 args = [self.genExprCode(e) for e in expr.args]
303 # Check arguments:
304 if type(expr.proc) is Identifier:
305 tg = self.resolveSymbol(expr.proc)
306 else:
307 raise Exception()
308 assert type(tg) is Function
309 ftyp = tg.typ
310 fname = tg.name
311 ptypes = ftyp.parametertypes
312 if len(expr.args) != len(ptypes):
313 raise SemanticError('Function {2}: {0} arguments required, {1} given'
314 .format(len(ptypes), len(expr.args), fname), expr.loc)
315 for arg, at in zip(expr.args, ptypes):
316 if not self.equalTypes(arg.typ, at):
317 raise SemanticError('Got {0}, expected {1}'
318 .format(arg.typ, at), arg.loc)
319 # determine return type:
320 expr.typ = ftyp.returntype
321 return ir.Call(fname, args)
322 else: 274 else:
323 raise NotImplementedError('Unknown expr {}'.format(expr)) 275 raise NotImplementedError('Unknown expr {}'.format(expr))
324 276
277 def gen_type_cast(self, expr):
278 """ Generate code for type casting """
279 ar = self.genExprCode(expr.a)
280 from_type = self.theType(expr.a.typ)
281 to_type = self.theType(expr.to_type)
282 if isinstance(from_type, ast.PointerType) and isinstance(to_type, ast.PointerType):
283 expr.typ = expr.to_type
284 return ar
285 elif type(from_type) is ast.BaseType and from_type.name == 'int' and \
286 isinstance(to_type, ast.PointerType):
287 expr.typ = expr.to_type
288 return ar
289 else:
290 raise SemanticError('Cannot cast {} to {}'
291 .format(from_type, to_type), expr.loc)
292
293 def gen_function_call(self, expr):
294 """ Generate code for a function call """
295 # Evaluate the arguments:
296 args = [self.genExprCode(e) for e in expr.args]
297 # Check arguments:
298 tg = self.resolveSymbol(expr.proc)
299 if type(tg) is not ast.Function:
300 raise SemanticError('cannot call {}'.format(tg))
301 ftyp = tg.typ
302 fname = tg.name
303 ptypes = ftyp.parametertypes
304 if len(expr.args) != len(ptypes):
305 raise SemanticError('{} requires {} arguments, {} given'
306 .format(fname, len(ptypes), len(expr.args)), expr.loc)
307 for arg, at in zip(expr.args, ptypes):
308 if not self.equalTypes(arg.typ, at):
309 raise SemanticError('Got {}, expected {}'
310 .format(arg.typ, at), arg.loc)
311 # determine return type:
312 expr.typ = ftyp.returntype
313 return ir.Call(fname, args)
314
325 def resolveSymbol(self, sym): 315 def resolveSymbol(self, sym):
326 assert type(sym) in [Identifier, Member] 316 if type(sym) is ast.Member:
327 if type(sym) is Member:
328 base = self.resolveSymbol(sym.base) 317 base = self.resolveSymbol(sym.base)
318 if type(base) is not ast.Package:
319 raise SemanticError('Base is not a package', sym.loc)
329 scope = base.innerScope 320 scope = base.innerScope
330 name = sym.field 321 name = sym.field
331 elif type(sym) is Identifier: 322 elif type(sym) is ast.Identifier:
332 scope = sym.scope 323 scope = sym.scope
333 name = sym.target 324 name = sym.target
334 else: 325 else:
335 raise NotImplementedError(str(sym)) 326 raise NotImplementedError(str(sym))
336 if name in scope: 327 if name in scope:
337 s = scope[name] 328 s = scope[name]
338 else: 329 else:
339 raise SemanticError('{} undefined'.format(name), sym.loc) 330 raise SemanticError('{} undefined'.format(name), sym.loc)
340 assert isinstance(s, Symbol) 331 assert isinstance(s, ast.Symbol)
341 return s 332 return s
342 333
343 def theType(self, t): 334 def theType(self, t):
344 """ Recurse until a 'real' type is found """ 335 """ Recurse until a 'real' type is found """
345 if type(t) is DefinedType: 336 if type(t) is ast.DefinedType:
346 t = self.theType(t.typ) 337 t = self.theType(t.typ)
347 elif type(t) is Identifier: 338 elif type(t) in [ast.Identifier, ast.Member]:
348 t = self.theType(self.resolveSymbol(t)) 339 t = self.theType(self.resolveSymbol(t))
349 elif type(t) is Member: 340 elif isinstance(t, ast.Type):
350 # Possible when using types of modules:
351 t = self.theType(self.resolveSymbol(t))
352 elif isinstance(t, Type):
353 pass 341 pass
354 else: 342 else:
355 raise NotImplementedError(str(t)) 343 raise NotImplementedError(str(t))
356 assert isinstance(t, Type) 344 assert isinstance(t, ast.Type)
357 return t 345 return t
358 346
359 def equalTypes(self, a, b): 347 def equalTypes(self, a, b):
360 """ Compare types a and b for structural equavalence. """ 348 """ Compare types a and b for structural equavalence. """
361 # Recurse into named types: 349 # Recurse into named types:
362 a = self.theType(a) 350 a = self.theType(a)
363 b = self.theType(b) 351 b = self.theType(b)
364 assert isinstance(a, Type) 352 assert isinstance(a, ast.Type)
365 assert isinstance(b, Type) 353 assert isinstance(b, ast.Type)
366 354
367 if type(a) is type(b): 355 if type(a) is type(b):
368 if type(a) is BaseType: 356 if type(a) is ast.BaseType:
369 return a.name == b.name 357 return a.name == b.name
370 elif type(a) is PointerType: 358 elif type(a) is ast.PointerType:
371 return self.equalTypes(a.ptype, b.ptype) 359 return self.equalTypes(a.ptype, b.ptype)
372 elif type(a) is StructureType: 360 elif type(a) is ast.StructureType:
373 if len(a.mems) != len(b.mems): 361 if len(a.mems) != len(b.mems):
374 return False 362 return False
375 return all(self.equalTypes(am.typ, bm.typ) for am, bm in 363 return all(self.equalTypes(am.typ, bm.typ) for am, bm in
376 zip(a.mems, b.mems)) 364 zip(a.mems, b.mems))
377 else: 365 else: