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 = []