Mercurial > lcfOS
diff python/c3/codegenerator.py @ 230:88a1e0baef65
Added some tests for IR-code
author | Windel Bouwman |
---|---|
date | Sat, 13 Jul 2013 19:53:44 +0200 |
parents | 7f18ed9b6b7e |
children | 521567d17388 |
line wrap: on
line diff
--- a/python/c3/codegenerator.py Sat Jul 13 11:13:01 2013 +0200 +++ b/python/c3/codegenerator.py Sat Jul 13 19:53:44 2013 +0200 @@ -2,6 +2,9 @@ from . import astnodes from .scope import boolType, intType from ppci import CompilerError +from .typecheck import resolveType + +tmpnames = {'+':'add', '-':'sub', '*': 'mul', '/':'div', '|':'or', '&':'and'} class CodeGenerator: """ Generates intermediate code from a package """ @@ -23,7 +26,7 @@ self.funcMap[s] = f for s in pkg.innerScope: if type(s) is astnodes.Variable: - v = self.builder.newVariable(s.name) + v = self.builder.newTmp(s.name) #self.builder.addIns(ir.Alloc(v)) self.varMap[s] = v elif type(s) is astnodes.Function: @@ -56,9 +59,7 @@ self.genCode(s) elif type(code) is astnodes.Assignment: re = self.genExprCode(code.rval) - # TODO: Handle pointers loc = self.genExprCode(code.lval) - # determine location of variable self.builder.addIns(ir.Store(loc, re)) elif type(code) is astnodes.ExpressionStatement: self.genExprCode(code.ex) @@ -94,6 +95,7 @@ self.builder.setBB(te) else: print('Unknown stmt:', code) + def genCondCode(self, expr, bbtrue, bbfalse): # Implement sequential logical operators assert expr.typ == boolType @@ -122,13 +124,25 @@ self.builder.addIns(ir.Branch(bbfalse)) else: print('Unknown cond', expr) + + def cast_to_rvalue(self, expr, loc): + """ Cast lvalue to rvalue if required """ + if hasattr(expr, 'expect_rvalue'): + # Load value from memory location: + tmp = self.builder.newTmp() + i = ir.Load(loc, tmp) + self.builder.addIns(i) + return tmp + if expr.lvalue: + return loc + def genExprCode(self, expr): + assert isinstance(expr, astnodes.Expression) if type(expr) is astnodes.Binop: ra = self.genExprCode(expr.a) rb = self.genExprCode(expr.b) ops = ['+', '-', '*', '/', '|', '&'] if expr.op in ops: - tmpnames = {'+':'add', '-':'sub', '*': 'mul', '/':'div', '|':'or', '&':'and'} tmp = self.builder.newTmp(tmpnames[expr.op]) op = expr.op ins = ir.BinaryOperator(tmp, op, ra, rb) @@ -153,11 +167,8 @@ # TODO return tmp elif type(expr) is astnodes.VariableUse: - tmp = self.builder.newTmp() loc = self.varMap[expr.target] - i = ir.Load(loc, tmp) - self.builder.addIns(i) - return tmp + return self.cast_to_rvalue(expr, loc) elif type(expr) is astnodes.Deref: # dereference pointer type: addr = self.genExprCode(expr.ptr) @@ -166,10 +177,16 @@ self.builder.addIns(ins) return tmp elif type(expr) is astnodes.FieldRef: - tmp = self.builder.newTmp('struct_mem' + expr.field) - #ins = ir.BinaryOperator( - # TODO: add offset? - return tmp + b = self.genExprCode(expr.base) + offset = self.builder.newTmp('off_' + expr.field) + bt = resolveType(expr.base.typ) + ofs = bt.fieldOffset(expr.field) + ins = ir.ImmLoad(offset, ofs) + self.builder.addIns(ins) + tmp2 = self.builder.newTmp('adr_' + expr.field) + ins = ir.BinaryOperator(tmp2, '+', b, offset) + self.builder.addIns(ins) + return self.cast_to_rvalue(expr, tmp2) elif type(expr) is astnodes.Literal: tmp = self.builder.newTmp() ins = ir.ImmLoad(tmp, expr.val) @@ -177,13 +194,16 @@ return tmp elif type(expr) is astnodes.TypeCast: ar = self.genExprCode(expr.a) - if isinstance(expr.to_type, astnodes.PointerType): + tt = resolveType(expr.to_type) + if isinstance(tt, astnodes.PointerType): if expr.a.typ is intType: return ar elif isinstance(expr.a.typ, astnodes.PointerType): return ar else: raise Exception() + else: + raise Exception("not implemented") elif type(expr) is astnodes.FunctionCall: tmp = self.builder.newTmp("res") args = []