changeset 105:6a303f835c6d

Removed compilers directory
author Windel Bouwman
date Mon, 31 Dec 2012 17:35:17 +0100
parents ed230e947dc6
children f2d980eef509
files python/bcanalyzer.py python/hexviewer.py python/ppci/__init__.py python/ppci/compilers/__init__.py python/ppci/compilers/kscompiler.py python/ppci/core/__init__.py python/ppci/core/bitreader.py python/ppci/core/function.py python/ppci/core/module.py python/ppci/frontends/ks/__init__.py python/zcc.py
diffstat 11 files changed, 185 insertions(+), 92 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/bcanalyzer.py	Mon Dec 31 17:35:17 2012 +0100
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+
+import sys, os, argparse
+from ppci.core import BitcodeReader
+
+if __name__ == '__main__':
+   parser = argparse.ArgumentParser(description='Bitcode analyzer')
+   parser.add_argument('bitcodefile', type=str, help='the bitcode file to analyze')
+   args = parser.parse_args()
+
+   try:
+      with open(args.bitcodefile, 'rb') as f:
+         bcr = BitcodeReader(f)
+         module = bcr.parseModule()
+   except IOError:
+      print('Failed to load {0}'.format(args.bitcodefile))
+      sys.exit(3)
+   print(module)
+
--- a/python/hexviewer.py	Sun Dec 30 22:31:55 2012 +0100
+++ b/python/hexviewer.py	Mon Dec 31 17:35:17 2012 +0100
@@ -26,16 +26,18 @@
       br2 = QBrush(Qt.yellow)
       painter.setBrush(br2)
       w = self.width()
-      byteWidth = self.fontWidth * 16 * 3
+      byteWidth = self.fontWidth * (16 * 3 - 1)
       painter.drawRect(addressWidth + 4, 2, byteWidth, h)
       asciiWidth = self.fontWidth * 16
       br2 = QBrush(Qt.gray)
       painter.setBrush(br2)
       painter.drawRect(addressWidth + byteWidth + 4, 2, asciiWidth, h)
-      for r in range(1, 10):
+      rows = int(h / self.fontHeight) + 1
+      offset = 0
+      for r in range(1, rows):
+         bts = self.getBytes(offset + r - 1)
          addr = '{0:08X}'.format(r << 16)
          painter.drawText(2, 2 + self.fontHeight * r, addr)
-         bts = bytes(range(16))
          x = addressWidth + 4
          for b in bts:
             b = '{0:02X}'.format(b)
@@ -46,8 +48,15 @@
             b = '{0}'.format(chr(b))
             painter.drawText(x, 2 + self.fontHeight * r, b)
             x += 1 * self.fontWidth
+   def getBytes(self, offset):
+      if self.hexfile.regions:
+         r = self.hexfile.regions[0]
+         chunks = [r.data[p:p+16] for p in range(0, len(r.data), 16)]
+         if len(chunks) > offset:
+            return chunks[offset]
+      return bytes()
    def setHexFile(self, hf):
-      self.hexFile = hf
+      self.hexfile = hf
       self.update()
 
 class BinViewMain(QMainWindow):
@@ -55,7 +64,6 @@
       super().__init__()
       self.bv = BinViewer()
       self.setCentralWidget(self.bv)
-      self.bv.setHexFile(hexfile.HexFile('audio.hex'))
       mb = self.menuBar()
       fileMenu = mb.addMenu("File")
       
@@ -74,5 +82,6 @@
    app = QApplication(sys.argv)
    bv = BinViewMain()
    bv.show()
+   bv.bv.setHexFile(hexfile.HexFile('audio.hex'))
    app.exec_()
 
--- a/python/ppci/__init__.py	Sun Dec 30 22:31:55 2012 +0100
+++ b/python/ppci/__init__.py	Mon Dec 31 17:35:17 2012 +0100
@@ -1,6 +1,4 @@
 # File to make this directory a package.
 
-from .compilers import KsCompiler
-
 version = '0.0.1'
 
--- a/python/ppci/compilers/__init__.py	Sun Dec 30 22:31:55 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-# File to make this directory a package.
-
-from .kscompiler import KsCompiler
-
--- a/python/ppci/compilers/kscompiler.py	Sun Dec 30 22:31:55 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-import hashlib
-# Import compiler components:
-from ..frontends.ks import KsParser
-from ..frontends.ks import KsIrGenerator
-#from .codegenerator import CodeGenerator
-#from .nodes import ExportedSymbol
-from ..core.errors import CompilerException
-from ..core.bitreader import BitcodeWriter
-from ..core import version, Context
-#from .. import version
-
-class KsCompiler:
-   def __repr__(self):
-      return 'LCFOS compiler {0}'.format(version)
-
-   def compilesource(self, src):
-      context = Context()
-      """ Front end that handles the stages: """
-      self.errorlist = []
-      # Pass 1: parsing and type checking
-      p = KsParser(src)
-      try:
-         ast = p.parseModule() # Parse a module into an AST
-      except CompilerException as e:
-         print(e)
-         p.errorlist.append( (e.row, e.col, e.msg) )
-      if len(p.errorlist) > 0:
-         self.errorlist = p.errorlist
-         return
-      ir = KsIrGenerator().generateIr(context, ast)
-      # pass 2: Optimization
-      # TODO: implement optimization
-
-      # Pass 3: code generation
-      return ast
-
--- a/python/ppci/core/__init__.py	Sun Dec 30 22:31:55 2012 +0100
+++ b/python/ppci/core/__init__.py	Mon Dec 31 17:35:17 2012 +0100
@@ -1,7 +1,7 @@
 from .instruction import *
 from .function import Function
 from .value import Value
-from .bitreader import BitReader, BitcodeWriter
+from .bitreader import BitcodeReader, BitcodeWriter
 from .errors import CompilerException
 from .module import Module
 from .llvmtype import FunctionType
--- a/python/ppci/core/bitreader.py	Sun Dec 30 22:31:55 2012 +0100
+++ b/python/ppci/core/bitreader.py	Mon Dec 31 17:35:17 2012 +0100
@@ -1,30 +1,90 @@
 from .errors import CompilerException
+from .module import Module
 import struct
 
-def bits(f):
-   while True:
-      Byte = f.read(1)
-      for i in range(8):
-         yield Byte & 0x1
-         Byte >>= 1
+def enum(**enums):
+   return type('Enum', (), enums)
+
+BitCodes = enum(END_BLOCK=0, ENTER_SUBBLOCK=1)
+
+class BitstreamReader:
+   def __init__(self, f):
+      self.f = f
+      # Initialize the bitreader:
+      self.bitsInCurrent = 32
+      self.curWord = self.getWord()
+      self.curCodeSize = 2
+   def getWord(self):
+      bts = self.f.read(4)
+      return struct.unpack('<I', bts)[0]
+   def Read(self, numbits):
+      if numbits > 32:
+         raise CompilerException("Cannot read more than 32 bits")
+      if self.bitsInCurrent >= numbits:
+         # numbits inside the current word:
+         R = self.curWord & ((1 << numbits) - 1)
+         self.curWord = self.curWord >> numbits
+         self.bitsInCurrent -= numbits
+         return R 
+      R = self.curWord
+      self.curWord = self.getWord()
+      bitsLeft = numbits - self.bitsInCurrent
+      
+      # Add remaining bits:
+      R |= (self.curWord & (0xFFFFFFFF >> (32 - bitsLeft))) << self.bitsInCurrent
 
-class BitReader:
+      # Update curword and bits in current:
+      self.curWord = self.curWord >> bitsLeft
+      self.bitsInCurrent = 32 - bitsLeft
+      return R
+   def ReadVBR(self, numbits):
+      """ Read variable bits, checking for the last bit is zero. """
+      piece = self.Read(numbits)
+      if (piece & (1 << (numbits - 1))) == 0:
+         return piece
+      result = 0
+      nextbit = 0
+      while True:
+         mask = (1 << (numbits - 1)) - 1
+         result |= ( piece & mask ) << nextbit
+         if (piece & (1 << (numbits - 1))) == 0:
+            return result
+         nextbit += numbits - 1
+         piece = self.Read(numbits)
+   def ReadCode(self):
+      """ Read the code depending on the current code size """
+      return self.Read(self.curCodeSize)
+   def ReadSubBlockId(self):
+      return self.ReadVBR(8)
+   def EnterSubBlock(self, blockId):
+      pass
+
+BLOCKINFO_BLOCKID = 0
+FIRST_APPLICATION_BLOCKID = 8
+MODULE_BLOCKID = FIRST_APPLICATION_BLOCKID
+
+class BitcodeReader:
    def __init__(self, f):
-      self.stream = bits(f)
-      self.curword = None
+      self.stream = BitstreamReader(f)
    def parseModule(self):
-      if self.read(8) != ord('B') or self.read(8) != ord('C'):
-         raise CompilerException('Invalid bitcode signature')
+      for bitsig in [ord('B'), ord('C')]:
+         if self.stream.Read(8) != bitsig:
+            raise CompilerException('Invalid bitcode signature')
       for bitsig in [0x0, 0xC, 0xE, 0xD]:
-         if self.read(4) != bitsig:
+         if self.stream.Read(4) != bitsig:
             raise CompilerException('Invalid bitcode signature')
-
-   def read(self, numbits):
-      if numbits == 8:
-         b = self.stream.read(1)
-         print(b)
-         return int(b[0])
-      return 2
+      while True:
+         code = self.stream.ReadCode()
+         if code != BitCodes.ENTER_SUBBLOCK:
+            raise CompilerException('Invalid record at toplevel')
+         blockId = self.stream.ReadSubBlockId()
+         if blockId == MODULE_BLOCKID:
+            print('module block')
+            pass
+         else:
+            print('Block id:', blockId)
+            raise 
+      return Module()
 
 class BitstreamWriter:
    def __init__(self, f):
--- a/python/ppci/core/function.py	Sun Dec 30 22:31:55 2012 +0100
+++ b/python/ppci/core/function.py	Mon Dec 31 17:35:17 2012 +0100
@@ -1,7 +1,22 @@
+
+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):
       self.functiontype = functiontype
       self.name = name
       self.module = module
+      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/ppci/core/module.py	Sun Dec 30 22:31:55 2012 +0100
+++ b/python/ppci/core/module.py	Mon Dec 31 17:35:17 2012 +0100
@@ -1,7 +1,16 @@
 
 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):
-      print('new module!')
+      self.functions = []
+      self.globals_ = []
+      self.symtable = SymbolTable()
+
+   Globals = property(lambda self: self.globals_)
+   Functions = property(lambda self: self.functions)
    
--- a/python/ppci/frontends/ks/__init__.py	Sun Dec 30 22:31:55 2012 +0100
+++ b/python/ppci/frontends/ks/__init__.py	Mon Dec 31 17:35:17 2012 +0100
@@ -1,13 +1,27 @@
-"""
- Frontend for the K# language.
-
- This module can parse K# code and create LLVM intermediate code.
-"""
 
 from .parser import KsParser
 from .irgenerator import KsIrGenerator
 
 class KsFrontend:
-   def __init__(self):
-      pass
+   """
+    Frontend for the K# language.
 
+    This module can parse K# code and create LLVM intermediate code.
+   """
+   def __init__(self, context):
+      self.context = context
+   def compilesource(self, src):
+      """ Front end that handles parsing and Module generation """
+      self.errorlist = []
+      # Pass 1: parsing and type checking
+      p = KsParser(src)
+      ast = p.parseModule() # Parse source into an AST
+
+      # Store ast:
+      self.ast = ast
+
+      # Generate ir (a core.Module):
+      ir = KsIrGenerator().generateIr(context, ast)
+
+      return ir
+
--- a/python/zcc.py	Sun Dec 30 22:31:55 2012 +0100
+++ b/python/zcc.py	Mon Dec 31 17:35:17 2012 +0100
@@ -1,26 +1,35 @@
 #!/usr/bin/python
 
 import sys, os, argparse
-from ppci.compilers import KsCompiler
-from ppci.core import BitcodeWriter
+from ppci import core
+
+parser = argparse.ArgumentParser(description='K# to bitcode compiler')
+parser.add_argument('source', type=str, help='the source file to build')
+args = parser.parse_args()
 
-if __name__ == '__main__':
-   parser = argparse.ArgumentParser(description='K# to bitcode compiler')
-   parser.add_argument('source', type=str, help='the source file to build')
-   args = parser.parse_args()
+try:
+   with open(args.source, 'r') as f:
+      src = f.read()
+except IOError:
+   print('Failed to load {0}'.format(args.source))
+   sys.exit(1)
 
-   print(args)
-   try:
-      with open(args.source, 'r') as f:
-         src = f.read()
-   except IOError:
-      print('Failed to load {0}'.format(args.project))
-      sys.exit(3)
-   c = KsCompiler()
-   module = c.compilesource(src)
+# Create a context and a frontend:
+context = core.Context()
+frontend = core.frontends.ks.KsFrontend(context)
+try:
+   module = frontend.compilesource(src)
+except core.CompilerException as e:
+   print(e)
+   sys.exit(2)
 
-   with open('sjaak.bc', 'wb') as f:
-      BitcodeWriter().WriteModuleToFile(module, f)
+# optionally run passes here:
+# TODO
+
+# Generate code:
+bitcodeWriter = core.BitcodeWriter()
+with open(args.source + '.bc', 'wb') as f:
+   bitcodeWriter.WriteModuleToFile(module, f)