Mercurial > lcfOS
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) |