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: