changeset 157:8f3924b6076e

Added some code generator things
author Windel Bouwman
date Sun, 03 Mar 2013 18:14:35 +0100
parents 1b4a85bdd99c
children 9683a4cd848f
files python/c3/codegenerator.py python/c3/parser.py python/ir/__init__.py python/ir/instruction.py python/ir/llvmtype.py python/ir/module.py python/testc3.py python/x86.py
diffstat 8 files changed, 100 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/python/c3/codegenerator.py	Sun Mar 03 15:50:34 2013 +0100
+++ b/python/c3/codegenerator.py	Sun Mar 03 18:14:35 2013 +0100
@@ -18,13 +18,45 @@
    m.Globals.append(v)
 
 def genFunction(m, fnc):
-   f = ir.Function()
+   ft = genType(fnc.typ)
+   f = ir.Function(fnc.name, ft)
    m.Globals.append(f)
+   bb = ir.BasicBlock()
+   f.BasicBlocks.append(bb)
+   genCode(bb, fnc.body)
+
+def genCode(bb, code):
+   if type(code) is astnodes.CompoundStatement:
+      for s in code.statements:
+         genCode(bb, s)
+   elif type(code) is astnodes.Assignment:
+      genCode(bb, code.rval)
+      print('assign')
+   elif type(code) is astnodes.IfStatement:
+      genCode(bb, code.condition)
+      genCode(bb, code.truestatement)
+      print('If!')
+   elif type(code) is astnodes.Binop:
+      genCode(bb, code.a)
+      genCode(bb, code.b)
+      a = 1
+      b = 2
+      if code.op == '+':
+         bb.Instructions.append(ir.AddInstruction(a, b))
+      else:
+         bb.Instructions.append(ir.BinaryOperator(code.op, a, b))
+   elif type(code) is astnodes.Constant:
+      print('CST')
+      bb.Instructions.append(ir.ImmLoadInstruction(code.value))
+   else:
+      print('Unknown:', code)
+
+def genType(t):
+   return ir.Type()
 
 class CodeGenerator:
    """ Generates intermediate code """
    def gencode(self, ast):
-      print('Code generator')
       assert type(ast) is astnodes.Package
       return genModule(ast)
 
--- a/python/c3/parser.py	Sun Mar 03 15:50:34 2013 +0100
+++ b/python/c3/parser.py	Sun Mar 03 18:14:35 2013 +0100
@@ -61,7 +61,6 @@
          self.parseFunctionDefinition()
       elif self.Peak == 'var':
          self.parseVarDef()
-         self.Consume(';')
       else:
          self.Error('Expected function or variable')
 
@@ -88,6 +87,7 @@
       parseVar()
       while self.hasConsumed(','):
          parseVar()
+      self.Consume(';')
 
    # Procedures
    def parseFunctionDefinition(self):
@@ -114,6 +114,7 @@
       lval = astnodes.VariableUse(lval)
       self.Consume('=')
       rval = self.parseExpression()
+      self.Consume(';')
       return astnodes.Assignment(lval, rval)
 
    def parseProcedureCall(self, procedure):
@@ -148,15 +149,14 @@
    def parseReturnStatement(self):
       self.Consume('return')
       expr = self.parseExpression()
+      self.Consume(';')
       return astnodes.ReturnStatement(expr)
 
    def parseCompoundStatement(self):
       self.Consume('{')
-      statements = [self.parseStatement()]
-      while self.hasConsumed(';'):
-         if self.Peak == '}': break # Permit last ';'
+      statements = []
+      while not self.hasConsumed('}'):
          statements.append(self.parseStatement())
-      self.Consume('}')
       return astnodes.CompoundStatement(statements)
 
    def parseStatement(self):
@@ -168,6 +168,7 @@
       elif self.Peak == '{':
          return self.parseCompoundStatement()
       elif self.Peak == ';':
+         self.Consume(';')
          return astnodes.EmptyStatement()
       elif self.Peak == 'var':
          return self.parseVarDef()
--- a/python/ir/__init__.py	Sun Mar 03 15:50:34 2013 +0100
+++ b/python/ir/__init__.py	Sun Mar 03 18:14:35 2013 +0100
@@ -1,4 +1,7 @@
 from .module import Module, Function, BasicBlock
 from .value import Value
-from .types import Type, i8, i16, i32, void
+from .module import Type, FunctionType
+from .module import i8, i16, i32, void
+from .instruction import AddInstruction, BinaryOperator, ImmLoadInstruction
 
+
--- a/python/ir/instruction.py	Sun Mar 03 15:50:34 2013 +0100
+++ b/python/ir/instruction.py	Sun Mar 03 18:14:35 2013 +0100
@@ -18,13 +18,17 @@
    def __init__(self, operation, value1, value2):
       assert value1
       assert value2
-      print('operation is in binops:', operation in BinOps)
+      #print('operation is in binops:', operation in BinOps)
       # Check types of the two operands:
       self.value1 = value1
       self.value2 = value2
       self.operation = operation
 
-class LoadInstruction(Instruction):
-   def __init__(self, ptr, name, insertBefore):
-      self.setName(name)
+class AddInstruction(BinaryOperator):
+   def __init__(self, a, b):
+      super().__init__('add', a, b)
 
+class ImmLoadInstruction(Instruction):
+   def __init__(self, value):
+      self.value = value
+
--- a/python/ir/llvmtype.py	Sun Mar 03 15:50:34 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-
-class Type:
-   def __init__(self):
-      pass
-      
-class IntegerType(Type):
-   def __init__(self, bits):
-      super().__init__()
-      self.bits = bits
-
-class VoidType(Type):
-   pass
-
-class FunctionType(Type):
-   def __init__(self, resultType, parameterTypes):
-      super().__init__()
-      assert type(parameterTypes) is list
-      self.resultType = resultType
-      self.parameterTypes = parameterTypes
-
-# Default types:
-i8 = IntegerType(8)
-i16 = IntegerType(16)
-i32 = IntegerType(32)
-void = VoidType()
-
-
--- a/python/ir/module.py	Sun Mar 03 15:50:34 2013 +0100
+++ b/python/ir/module.py	Sun Mar 03 18:14:35 2013 +0100
@@ -1,5 +1,33 @@
 from .symboltable import SymbolTable
 
+# Types:
+class Type:
+   def __init__(self):
+      pass
+      
+class IntegerType(Type):
+   def __init__(self, bits):
+      super().__init__()
+      self.bits = bits
+
+class VoidType(Type):
+   pass
+
+class FunctionType(Type):
+   def __init__(self, resultType, parameterTypes):
+      super().__init__()
+      assert type(parameterTypes) is list
+      self.resultType = resultType
+      self.parameterTypes = parameterTypes
+
+# Default types:
+i8 = IntegerType(8)
+i16 = IntegerType(16)
+i32 = IntegerType(32)
+void = VoidType()
+
+# IR-Structures:
+
 class Module:
    """ Main container for a piece of code. Contains globals and functions. """
    def __init__(self, name):
@@ -23,10 +51,8 @@
       self.name = name
       self.functiontype = functiontype
 
-      self.module.Functions.append(self)
       self.basicblocks = []
       self.arguments = []
-      # Construct formal arguments depending on function type
    BasicBlocks = property(lambda self: self.basicblocks)
    Arguments = property(lambda self: self.arguments)
    ReturnType = property(lambda self: self.functiontype.returnType)
--- a/python/testc3.py	Sun Mar 03 15:50:34 2013 +0100
+++ b/python/testc3.py	Sun Mar 03 18:14:35 2013 +0100
@@ -1,4 +1,4 @@
-import c3, time, ppci
+import c3, time, ppci, x86
 
 testsrc = """
 package test;
@@ -16,20 +16,24 @@
     var int zero = i - 2;
     if (i > 1)
     {
-       buf = b + 22 * i - 13 + (55 * 2 *9-2) / 44 - 1
+       buf = b + 22 * i - 13 + (55 * 2 *9-2) / 44 - 1;
     }
     else
     {
       ;;;
-    };
+    }
 
     t2(2, 3);
 }
 
 function int t2(u32 a, u32 b)
 {
+   if (a > 0)
+   {
+      a = 2 + t2(a - 1);
+   }
+
    return a + b;
-   a = 2;// + t2(2);
 }
 
 var int hahaa = 23 * 2;
@@ -57,6 +61,7 @@
    tc = c3.TypeChecker(diag)
    al = c3.Analyzer(diag)
    cg = c3.CodeGenerator()
+   x86gen = x86.X86CodeGen(diag)
    t1 = time.time()
    p.parseSource(src)
    t2 = time.time() 
@@ -77,8 +82,10 @@
    if ok:
       print('Generating code')
       i = cg.gencode(sema.mod)
+
       print(i)
       print(i.Globals)
+      x86gen.genBin(i)
    else:
       print('Not generating code')
    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/x86.py	Sun Mar 03 18:14:35 2013 +0100
@@ -0,0 +1,9 @@
+import ppci
+
+class X86CodeGen:
+   def __init__(self, diag):
+      self.diag = diag
+
+   def genBin(self, i):
+      print(i)
+