Mercurial > lcfOS
diff python/ppci/c3/codegenerator.py @ 393:6ae782a085e0
Added init program
author | Windel Bouwman |
---|---|
date | Sat, 17 May 2014 21:17:40 +0200 |
parents | 2ec730e45ea1 |
children | 988f3fb861e4 |
line wrap: on
line diff
--- a/python/ppci/c3/codegenerator.py Fri May 16 13:05:10 2014 +0200 +++ b/python/ppci/c3/codegenerator.py Sat May 17 21:17:40 2014 +0200 @@ -113,8 +113,8 @@ elif type(code) is ast.Empty: pass elif type(code) is ast.Assignment: - lval = self.genExprCode(code.lval) - rval = self.genExprCode(code.rval) + lval = self.gen_expr_code(code.lval) + rval = self.gen_expr_code(code.rval) if not self.equal_types(code.lval.typ, code.rval.typ): raise SemanticError('Cannot assign {} to {}' .format(code.rval.typ, code.lval.typ), @@ -124,7 +124,7 @@ code.lval.loc) self.emit(ir.Move(lval, rval)) elif type(code) is ast.ExpressionStatement: - self.emit(ir.Exp(self.genExprCode(code.ex))) + self.emit(ir.Exp(self.gen_expr_code(code.ex))) elif type(code) is ast.If: bbtrue = self.newBlock() bbfalse = self.newBlock() @@ -138,7 +138,7 @@ self.emit(ir.Jump(te)) self.setBlock(te) elif type(code) is ast.Return: - re = self.genExprCode(code.expr) + re = self.gen_expr_code(code.expr) self.emit(ir.Move(self.fn.return_value, re)) self.emit(ir.Jump(self.fn.epiloog)) b = self.newBlock() @@ -167,6 +167,8 @@ self.genCode(code.final) self.emit(ir.Jump(bbtest)) self.setBlock(te) + elif type(code) is ast.Switch: + raise NotImplementedError('Unknown stmt {}'.format(code)) else: raise NotImplementedError('Unknown stmt {}'.format(code)) @@ -193,8 +195,8 @@ if not self.equal_types(expr.b.typ, self.boolType): raise SemanticError('Must be boolean', expr.b.loc) elif expr.op in ['==', '>', '<', '!=', '<=', '>=']: - ta = self.genExprCode(expr.a) - tb = self.genExprCode(expr.b) + ta = self.gen_expr_code(expr.a) + tb = self.gen_expr_code(expr.b) if not self.equal_types(expr.a.typ, expr.b.typ): raise SemanticError('Types unequal {} != {}' .format(expr.a.typ, expr.b.typ), @@ -204,7 +206,7 @@ raise SemanticError('non-bool: {}'.format(expr.op), expr.loc) expr.typ = self.boolType elif type(expr) is ast.Literal: - self.genExprCode(expr) + self.gen_expr_code(expr) if expr.val: self.emit(ir.Jump(bbtrue)) else: @@ -216,17 +218,21 @@ if not self.equal_types(expr.typ, self.boolType): self.error('Condition must be boolean', expr.loc) - def genExprCode(self, expr): + def gen_expr_code(self, expr): """ Generate code for an expression. Return the generated ir-value """ assert isinstance(expr, ast.Expression) if type(expr) is ast.Binop: expr.lvalue = False if expr.op in ['+', '-', '*', '/', '<<', '>>', '|', '&']: - ra = self.genExprCode(expr.a) - rb = self.genExprCode(expr.b) + ra = self.gen_expr_code(expr.a) + rb = self.gen_expr_code(expr.b) if self.equal_types(expr.a.typ, self.intType) and \ self.equal_types(expr.b.typ, self.intType): expr.typ = expr.a.typ + elif self.equal_types(expr.b.typ, self.intType) and \ + type(expr.a.typ) is ast.PointerType: + # Special case for pointer arithmatic TODO: coerce! + expr.typ = expr.a.typ else: raise SemanticError('Can only add integers', expr.loc) else: @@ -234,7 +240,7 @@ return ir.Binop(ra, expr.op, rb) elif type(expr) is ast.Unop: if expr.op == '&': - ra = self.genExprCode(expr.a) + ra = self.gen_expr_code(expr.a) expr.typ = ast.PointerType(expr.a.typ) if not expr.a.lvalue: raise SemanticError('No valid lvalue', expr.a.loc) @@ -253,13 +259,13 @@ expr.lvalue = True return ir.Mem(self.varMap[tg]) elif isinstance(tg, ast.Constant): - c_val = self.genExprCode(tg.value) + c_val = self.gen_expr_code(tg.value) return self.evalConst(c_val) else: raise NotImplementedError(str(tg)) elif type(expr) is ast.Deref: # dereference pointer type: - addr = self.genExprCode(expr.ptr) + addr = self.gen_expr_code(expr.ptr) ptr_typ = self.the_type(expr.ptr.typ) expr.lvalue = True if type(ptr_typ) is ast.PointerType: @@ -268,7 +274,7 @@ else: raise SemanticError('Cannot deref non-pointer', expr.loc) elif type(expr) is ast.Member: - base = self.genExprCode(expr.base) + base = self.gen_expr_code(expr.base) expr.lvalue = expr.base.lvalue basetype = self.the_type(expr.base.typ) if type(basetype) is ast.StructureType: @@ -288,8 +294,8 @@ return ir.Mem(ir.Add(base.e, offset)) elif type(expr) is ast.Index: """ Array indexing """ - base = self.genExprCode(expr.base) - idx = self.genExprCode(expr.i) + base = self.gen_expr_code(expr.base) + idx = self.gen_expr_code(expr.i) base_typ = self.the_type(expr.base.typ) if not isinstance(base_typ, ast.ArrayType): raise SemanticError('Cannot index non-array type {}' @@ -325,6 +331,12 @@ return ir.Const(expr.val) elif type(expr) is ast.TypeCast: return self.gen_type_cast(expr) + elif type(expr) is ast.Sizeof: + # The type of this expression is int: + expr.typ = self.intType + self.check_type(expr.query_typ) + type_size = self.size_of(expr.query_typ) + return ir.Const(type_size) elif type(expr) is ast.FunctionCall: return self.gen_function_call(expr) else: @@ -338,7 +350,7 @@ def gen_type_cast(self, expr): """ Generate code for type casting """ - ar = self.genExprCode(expr.a) + ar = self.gen_expr_code(expr.a) from_type = self.the_type(expr.a.typ) to_type = self.the_type(expr.to_type) if isinstance(from_type, ast.PointerType) and \ @@ -364,7 +376,7 @@ def gen_function_call(self, expr): """ Generate code for a function call """ # Evaluate the arguments: - args = [self.genExprCode(e) for e in expr.args] + args = [self.gen_expr_code(e) for e in expr.args] # Check arguments: tg = self.resolveSymbol(expr.proc) if type(tg) is not ast.Function: