changeset 155:b28a11c01dbe

Simplified IR classes
author Windel Bouwman
date Sun, 03 Mar 2013 13:20:03 +0100
parents 81e08e2e7777
children 1b4a85bdd99c
files python/c3/astnodes.py python/c3/codegenerator.py python/c3/parser.py python/c3/scope.py python/c3/typecheck.py python/ir/__init__.py python/ir/basicblock.py python/ir/function.py python/ir/instruction.py python/ir/module.py python/ir/value.py python/testc3.py
diffstat 12 files changed, 93 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/python/c3/astnodes.py	Sat Mar 02 10:19:38 2013 +0100
+++ b/python/c3/astnodes.py	Sun Mar 03 13:20:03 2013 +0100
@@ -144,6 +144,9 @@
    def __repr__(self):
       return 'COMPOUND STATEMENT'
 
+class EmptyStatement(Node):
+   pass
+
 class ReturnStatement(Node):
    def __init__(self, expr):
       self.expr = expr
--- a/python/c3/codegenerator.py	Sat Mar 02 10:19:38 2013 +0100
+++ b/python/c3/codegenerator.py	Sun Mar 03 13:20:03 2013 +0100
@@ -1,8 +1,23 @@
+import ir
+from . import astnodes
 
-#from ppci import ircode
+def genModule(pkg):
+   m = ir.Module(pkg.name)
+   for s in pkg.scope:
+      print(s)
+      if type(s) is astnodes.Variable:
+         genGlobal(m, s)
+   return m
+
+def genGlobal(m, var):
+   v = ir.Value()
+   v.name = var.name
+   m.Globals.append(v)
 
 class CodeGenerator:
    """ Generates intermediate code """
    def gencode(self, ast):
-      pass
+      print('Code generator')
+      assert type(ast) is astnodes.Package
+      return genModule(ast)
 
--- a/python/c3/parser.py	Sat Mar 02 10:19:38 2013 +0100
+++ b/python/c3/parser.py	Sun Mar 03 13:20:03 2013 +0100
@@ -124,7 +124,7 @@
          while self.hasConsumed(','):
             args.append(self.parseExpression())
          self.Consume(')')
-      return ProcedureCall(procedure, args)
+      return astnodes.ProcedureCall(procedure, args)
 
    def parseIfStatement(self):
       self.Consume('if')
@@ -154,6 +154,7 @@
       self.Consume('{')
       statements = [self.parseStatement()]
       while self.hasConsumed(';'):
+         if self.Peak == '}': break # Permit last ';'
          statements.append(self.parseStatement())
       self.Consume('}')
       return astnodes.CompoundStatement(statements)
@@ -166,6 +167,8 @@
          return self.parseWhileStatement()
       elif self.Peak == '{':
          return self.parseCompoundStatement()
+      elif self.Peak == ';':
+         return astnodes.EmptyStatement()
       elif self.Peak == 'var':
          return self.parseVarDef()
       elif self.Peak == 'return':
@@ -191,7 +194,10 @@
          return self.sema.actOnNumber(val.val, val.loc)
       elif self.Peak == 'ID':
          d = self.parseDesignator()
-         return self.sema.actOnVariableUse(d)
+         if self.Peak == '(':
+            return self.parseProcedureCall(d)
+         else:
+            return self.sema.actOnVariableUse(d)
       self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak))
 
    def parseBinopRhs(self, lhs, min_prec):
--- a/python/c3/scope.py	Sat Mar 02 10:19:38 2013 +0100
+++ b/python/c3/scope.py	Sun Mar 03 13:20:03 2013 +0100
@@ -24,10 +24,9 @@
       self.symbols[sym.name] = sym
 
 def createBuiltins(scope):
-   for tn in ['int', 'u32', 'u16', 'double']:
+   for tn in ['int', 'u32', 'u16', 'double', 'void']:
       scope.addSymbol(astnodes.BaseType(tn))
 
 topScope = Scope()
-
 createBuiltins(topScope)
 
--- a/python/c3/typecheck.py	Sat Mar 02 10:19:38 2013 +0100
+++ b/python/c3/typecheck.py	Sun Mar 03 13:20:03 2013 +0100
@@ -1,7 +1,7 @@
 from .astnodes import BaseType, Variable, Designator, Function
 from .astnodes import CompoundStatement, Assignment, VariableUse
 from .astnodes import Binop, Unop, Constant
-from .astnodes import IfStatement, WhileStatement, ReturnStatement
+from .astnodes import IfStatement, WhileStatement, ReturnStatement, ProcedureCall
 from .astnodes import FunctionType, BaseType
 from . import astnodes
 from .scope import topScope
@@ -32,12 +32,14 @@
             self.check(s)
       elif type(sym) is IfStatement:
          self.check(sym.condition)
-         print(sym.condition)
          self.check(sym.truestatement)
          self.check(sym.falsestatement)
       elif type(sym) is VariableUse:
          if type(sym.target) is Designator:
             sym.target = self.resolveDesignator(sym.target)
+      elif type(sym) is ProcedureCall:
+         if type(sym.proc) is Designator:
+            sym.proc = self.resolveDesignator(sym.proc)
       elif type(sym) is Assignment:
          self.check(sym.lval)
          self.check(sym.rval)
--- a/python/ir/__init__.py	Sat Mar 02 10:19:38 2013 +0100
+++ b/python/ir/__init__.py	Sun Mar 03 13:20:03 2013 +0100
@@ -1,14 +1,3 @@
-from .instruction import BinaryOperator
-from .function import Function
-from .value import Value, Constant
-from .bitreader import BitcodeReader, BitcodeWriter
-from .errors import CompilerException
-from .module import Module
-from .llvmtype import FunctionType, i8, i16, i32, void
-from .context import Context
-from .asmwriter import AsmWriter
-from .basicblock import BasicBlock
-from .irbuilder import IRBuilder
+from .module import Module, Function, BasicBlock
+from .value import Value
 
-version='0.0.1'
-
--- a/python/ir/basicblock.py	Sat Mar 02 10:19:38 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-from .value import Value
-
-class BasicBlock(Value):
-   """ 
-     A basic block represents a sequence of instructions without
-     jumps and branches.
-   """
-   def __init__(self):
-      super().__init__()
-      self.instructions = []
-      self.name = None
-   def getInstructions(self):
-      return self.instructions
-   Instructions = property(getInstructions)
-
--- a/python/ir/function.py	Sat Mar 02 10:19:38 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-
-class Argument:
-   def __init__(self, argtype, name, function):
-      self.t = argtype
-      self.name = name
-      self.function = function
-
-class Function(GlobalValue):
-   def __init__(self, functiontype, name, module):
-      super().__init__()
-      self.functiontype = functiontype
-      self.name = name
-      self.module = module
-
-      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)
-   FunctionType = property(lambda self: self.functiontype)
-
--- a/python/ir/instruction.py	Sat Mar 02 10:19:38 2013 +0100
+++ b/python/ir/instruction.py	Sun Mar 03 13:20:03 2013 +0100
@@ -1,10 +1,8 @@
-
-from .value import Value
 
 def Enum(**enums):
    return type('Enum', (), enums)
 
-class Instruction(Value):
+class Instruction:
    """ Base class for all instructions. """
    pass
 
--- a/python/ir/module.py	Sat Mar 02 10:19:38 2013 +0100
+++ b/python/ir/module.py	Sun Mar 03 13:20:03 2013 +0100
@@ -1,12 +1,9 @@
-from .value import Value
 from .symboltable import SymbolTable
 
-class Module(Value):
-   """
-      Main container for a piece of code. Contains globals and functions.
-   """
-   def __init__(self, identifier=None):
-      self.identifier = identifier
+class Module:
+   """ Main container for a piece of code. Contains globals and functions. """
+   def __init__(self, name):
+      self.name = name
       self.functions = [] # Do functions come out of symbol table?
       self.globals_ = [] # TODO: are globals in symbol table?
       self.symtable = SymbolTable()
@@ -14,4 +11,40 @@
    Globals = property(lambda self: self.globals_)
    Functions = property(lambda self: self.functions)
    Identifier = property(lambda self: self.identifier)
+
+class Argument:
+   def __init__(self, argtype, name, function):
+      self.t = argtype
+      self.name = name
+      self.function = function
+
+class Function:
+   def __init__(self, functiontype, name, module):
+      super().__init__()
+      self.functiontype = functiontype
+      self.name = name
+      self.module = module
+
+      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)
+   FunctionType = property(lambda self: self.functiontype)
    
+class BasicBlock:
+   """ 
+     A basic block represents a sequence of instructions without
+     jumps and branches.
+   """
+   def __init__(self):
+      super().__init__()
+      self.instructions = []
+      self.name = None
+   def getInstructions(self):
+      return self.instructions
+   Instructions = property(getInstructions)
+
--- a/python/ir/value.py	Sat Mar 02 10:19:38 2013 +0100
+++ b/python/ir/value.py	Sun Mar 03 13:20:03 2013 +0100
@@ -7,18 +7,12 @@
       return self.valueType.context
    def dump(self):
       print(self)
-
    def getName(self):
       return self.name
    def setName(self, name):
       if not self.name and not name:
          return
       self.name = name
-
-      if self.st:
-         pass
-      else:
-         pass
    Name = property(getName, setName)
 
 class Constant(Value):
--- a/python/testc3.py	Sat Mar 02 10:19:38 2013 +0100
+++ b/python/testc3.py	Sun Mar 03 13:20:03 2013 +0100
@@ -10,30 +10,30 @@
     var u32 b;
     var int a = 10;
     b = 20;
-    var int88 buf;
+    var int buf;
     var int i;
     i = 2;
-    zero = i - 2;
+    var int zero = i - 2;
     if (i > 1)
     {
-       buf = b + 22 * i - 13 + (55 * 2 *9-2) / 44 - one
+       buf = b + 22 * i - 13 + (55 * 2 *9-2) / 44 - 1
     }
+    else
+    {
+      ;;;
+    };
+
+    t2(2, 3);
 }
 
 function int t2(u32 a, u32 b)
 {
    return a + b;
-   a = 2
+   a = 2;// + t2(2);
 }
 
-var u8 hahaa = 23 * 2;
+var int hahaa = 23 * 2;
 
-function int t2(u32 a, u32 b)
-{
-   return a + b;
-   a = 2 + 33 * 1 - 3;
-   a = a - 2
-}
 
 """
 
@@ -50,7 +50,7 @@
 
 def c3compile(src, diag):
    print('[0] source:')
-   print(src)
+   #print(src)
    print('[1] parsing')
    sema = c3.Semantics(diag)
    p = c3.Parser(sema, diag)
@@ -71,11 +71,14 @@
       print('ERROR:')
       ppci.printError(testsrc, d)
    print('[2] ast:')
-   printAst(sema.mod)
+   #printAst(sema.mod)
 
    ok = len(diag.diags) == 0
    if ok:
-      cg.gencode(sema.mod)
+      print('Generating code')
+      i = cg.gencode(sema.mod)
+      print(i)
+      print(i.Globals)
    else:
       print('Not generating code')