comparison python/ppci/c3/codegenerator.py @ 313:04cf4d26a3bc

Added constant function
author Windel Bouwman
date Wed, 18 Dec 2013 18:02:26 +0100
parents 2c9768114877
children 084cccaa5deb
comparison
equal deleted inserted replaced
312:2c9768114877 313:04cf4d26a3bc
32 self.prepare() 32 self.prepare()
33 assert type(pkg) is ast.Package 33 assert type(pkg) is ast.Package
34 self.pkg = pkg 34 self.pkg = pkg
35 self.intType = pkg.scope['int'] 35 self.intType = pkg.scope['int']
36 self.boolType = pkg.scope['bool'] 36 self.boolType = pkg.scope['bool']
37 self.logger.info('Generating ir-code for {}'.format(pkg.name)) 37 self.logger.info('Generating ir-code for {}'.format(pkg.name), extra={'c3_ast':pkg})
38 self.varMap = {} # Maps variables to storage locations. 38 self.varMap = {} # Maps variables to storage locations.
39 self.funcMap = {} 39 self.funcMap = {}
40 self.m = ir.Module(pkg.name) 40 self.m = ir.Module(pkg.name)
41 try: 41 try:
42 for s in pkg.innerScope.Functions: 42 for s in pkg.innerScope.Functions:
46 self.varMap[v] = self.newTemp() 46 self.varMap[v] = self.newTemp()
47 for s in pkg.innerScope.Functions: 47 for s in pkg.innerScope.Functions:
48 self.gen_function(s) 48 self.gen_function(s)
49 except SemanticError as e: 49 except SemanticError as e:
50 self.error(e.msg, e.loc) 50 self.error(e.msg, e.loc)
51 return self.m 51 if self.pkg.ok:
52 return self.m
52 53
53 def error(self, msg, loc=None): 54 def error(self, msg, loc=None):
54 self.pkg.ok = False 55 self.pkg.ok = False
55 self.diag.error(msg, loc) 56 self.diag.error(msg, loc)
56 57
68 self.setBlock(l2) 69 self.setBlock(l2)
69 # generate room for locals: 70 # generate room for locals:
70 71
71 for sym in fn.innerScope: 72 for sym in fn.innerScope:
72 # TODO: handle parameters different 73 # TODO: handle parameters different
74 self.checkType(sym.typ)
73 if sym.isParameter: 75 if sym.isParameter:
74 self.checkType(sym.typ)
75 variable = ir.Parameter(sym.name) 76 variable = ir.Parameter(sym.name)
76 f.addParameter(variable) 77 f.addParameter(variable)
77 elif sym.isLocal: 78 elif sym.isLocal:
78 self.checkType(sym.typ)
79 variable = ir.LocalVariable(sym.name) 79 variable = ir.LocalVariable(sym.name)
80 f.addLocal(variable) 80 f.addLocal(variable)
81 elif isinstance(sym, ast.Variable): 81 elif isinstance(sym, ast.Variable):
82 self.checkType(sym.typ)
83 variable = ir.LocalVariable(sym.name) 82 variable = ir.LocalVariable(sym.name)
84 f.addLocal(variable) 83 f.addLocal(variable)
85 else: 84 else:
86 raise NotImplementedError('{}'.format(sym)) 85 raise NotImplementedError('{}'.format(sym))
87 self.varMap[sym] = variable 86 self.varMap[sym] = variable
220 return ra.e 219 return ra.e
221 else: 220 else:
222 raise NotImplementedError('Unknown unop {0}'.format(expr.op)) 221 raise NotImplementedError('Unknown unop {0}'.format(expr.op))
223 elif type(expr) is ast.Identifier: 222 elif type(expr) is ast.Identifier:
224 # Generate code for this identifier. 223 # Generate code for this identifier.
225 expr.lvalue = True
226 tg = self.resolveSymbol(expr) 224 tg = self.resolveSymbol(expr)
227 expr.kind = type(tg) 225 expr.kind = type(tg)
228 expr.typ = tg.typ 226 expr.typ = tg.typ
229 # This returns the dereferenced variable. 227 # This returns the dereferenced variable.
230 if isinstance(tg, ast.Variable): 228 if isinstance(tg, ast.Variable):
229 expr.lvalue = True
231 return ir.Mem(self.varMap[tg]) 230 return ir.Mem(self.varMap[tg])
231 elif isinstance(tg, ast.Constant):
232 c_val = self.genExprCode(tg.value)
233 return self.evalConst(c_val)
232 else: 234 else:
233 raise NotImplementedError(str(tg)) 235 raise NotImplementedError(str(tg))
234 elif type(expr) is ast.Deref: 236 elif type(expr) is ast.Deref:
235 # dereference pointer type: 237 # dereference pointer type:
236 addr = self.genExprCode(expr.ptr) 238 addr = self.genExprCode(expr.ptr)
259 bt = self.theType(expr.base.typ) 261 bt = self.theType(expr.base.typ)
260 offset = ir.Const(bt.fieldOffset(expr.field)) 262 offset = ir.Const(bt.fieldOffset(expr.field))
261 return ir.Mem(ir.Add(base.e, offset)) 263 return ir.Mem(ir.Add(base.e, offset))
262 elif type(expr) is ast.Literal: 264 elif type(expr) is ast.Literal:
263 expr.lvalue = False 265 expr.lvalue = False
264 typemap = {int: 'int', float: 'double', bool: 'bool'} 266 typemap = {int: 'int', float: 'double', bool: 'bool', str:'string'}
265 if type(expr.val) in typemap: 267 if type(expr.val) in typemap:
266 expr.typ = self.pkg.scope[typemap[type(expr.val)]] 268 expr.typ = self.pkg.scope[typemap[type(expr.val)]]
267 else: 269 else:
268 raise SemanticError('Unknown literal type {}'.format(expr.val), expr.loc) 270 raise SemanticError('Unknown literal type {}'.format(expr.val), expr.loc)
269 return ir.Const(expr.val) 271 return ir.Const(expr.val)
310 .format(arg.typ, at), arg.loc) 312 .format(arg.typ, at), arg.loc)
311 # determine return type: 313 # determine return type:
312 expr.typ = ftyp.returntype 314 expr.typ = ftyp.returntype
313 return ir.Call(fname, args) 315 return ir.Call(fname, args)
314 316
317 def evalConst(self, c):
318 if isinstance(c, ir.Const):
319 return c
320 else:
321 raise SemanticError('Cannot evaluate constant {}'.format(c))
322
315 def resolveSymbol(self, sym): 323 def resolveSymbol(self, sym):
316 if type(sym) is ast.Member: 324 if type(sym) is ast.Member:
317 base = self.resolveSymbol(sym.base) 325 base = self.resolveSymbol(sym.base)
318 if type(base) is not ast.Package: 326 if type(base) is not ast.Package:
319 raise SemanticError('Base is not a package', sym.loc) 327 raise SemanticError('Base is not a package', sym.loc)