changeset 101:af0d7913677a

Fixes and splitting into 3 stage
author windel
date Mon, 24 Dec 2012 17:55:08 +0100
parents fe145e42259d
children 63937c8d1478
files python/build.py python/codeeditor.py python/ide.py python/ppci/compilers/kscompiler.py python/ppci/core/__init__.py python/ppci/display.py python/ppci/frontends/ks/__init__.py python/ppci/frontends/ks/lexer.py python/ppci/frontends/ks/nodes.py python/ppci/frontends/ks/parser.py
diffstat 10 files changed, 82 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/python/build.py	Mon Dec 24 16:35:22 2012 +0100
+++ b/python/build.py	Mon Dec 24 17:55:08 2012 +0100
@@ -1,5 +1,6 @@
+#!/usr/bin/python
+
 import sys, os, argparse
-sys.path.insert(0, os.path.join('..','libs'))
 
 # Compiler imports:
 from compiler import Compiler
--- a/python/codeeditor.py	Mon Dec 24 16:35:22 2012 +0100
+++ b/python/codeeditor.py	Mon Dec 24 17:55:08 2012 +0100
@@ -68,22 +68,25 @@
       self.filename = filename
       self.isUntitled = False
       self.setWindowTitle(filename)
+
    def setSource(self, source):
       self.setPlainText(source)
+   def getSource(self):
+      return self.toPlainText()
+   source = property(getSource, setSource)
 
    def save(self):
-      pass
+      self.saveFile()
    def saveAs(self):
-      pass
+      print('save as')
 
    def saveFile(self):
       if self.isUntitled:
          self.saveAs()
       else:
          source = str(self.toPlainText())
-         f = open(self.filename, 'w')
-         f.write(source)
-         f.close()
+         with open(self.filename, 'w') as f:
+            f.write(source)
 
    def highlightErrorLocation(self, row, col):
       tc = QTextCursor(self.document())
--- a/python/ide.py	Mon Dec 24 16:35:22 2012 +0100
+++ b/python/ide.py	Mon Dec 24 17:55:08 2012 +0100
@@ -124,6 +124,7 @@
 
     # Create menus:
     mb = self.menuBar()
+    self.fileMenu = mb.addMenu('File')
     self.projectMenu = mb.addMenu('Project')
     self.viewMenu = mb.addMenu('View')
     self.helpMenu = mb.addMenu('Help')
@@ -166,6 +167,11 @@
     addMenuEntry("Close", self.projectMenu, self.closeProject)
     addMenuEntry("Build", self.projectMenu, self.buildProject, shortcut=QKeySequence('F7'))
 
+    addMenuEntry("New", self.fileMenu, self.newFile, shortcut=QKeySequence(QKeySequence.New))
+    addMenuEntry("Open", self.fileMenu, self.openFile, shortcut=QKeySequence(QKeySequence.Open))
+    addMenuEntry("Save", self.fileMenu, self.saveFile, shortcut=QKeySequence(QKeySequence.Save))
+    addMenuEntry("Build", self.fileMenu, self.buildFile, shortcut=QKeySequence("F8"))
+
     self.helpAction  = QAction('Help', self)
     self.helpAction.setShortcut(QKeySequence('F1'))
     self.helpMenu.addAction(self.helpAction)
@@ -187,6 +193,17 @@
         self.project.filename = filename
         self.project.save()
 
+  def newFile(self):
+     self.loadFile('main.ks')
+  def openFile(self):
+     filename = QFileDialog.getOpenFileName(self, "Open K# file...", "*.ks", "K# source files (*.ks)")
+     if filename:
+        self.loadFile(filename)
+  def saveFile(self):
+     ac = self.activeMdiChild()
+     if ac:
+         ac.save()
+
   def saveProject(self):
      self.project.save()
 
@@ -204,9 +221,16 @@
 
      # Create a new one:
      ce = CodeEdit()
-     source = self.project.loadProjectFile(filename)
-     ce.setSource(source)
+
+     #source = self.project.loadProjectFile(filename)
+     try:
+        with open(filename) as f:
+          source = f.read()
+          ce.setSource(source)
+     except Exception as e:
+        print('exception opening file', e)
      self.mdiArea.addSubWindow(ce)
+     ce.setFileName(filename)
      ce.show()
      return ce
 
@@ -251,13 +275,19 @@
      if self.settings.contains('openedproject'):
         projectfile = self.settings.value('openedproject')
         #self.loadProject(projectfile)
+     if self.settings.contains('lastfile'):
+        self.loadFile(self.settings.value('lastfile'))
   
   def closeEvent(self, ev):
      self.settings.setValue('mainwindowstate', self.saveState())
      self.settings.setValue('mainwindowgeometry', self.saveGeometry())
-     if self.project:
-        self.settings.setValue('openedproject', self.project.filename)
-        # TODO: ask for save of opened files
+     #if self.project:
+     #   self.settings.setValue('openedproject', self.project.filename)
+     #   # TODO: ask for save of opened files
+     ac = self.activeMdiChild()
+     if ac:
+        if ac.filename:
+           self.settings.setValue('lastfile', ac.filename)
      ev.accept()
 
   # Error handling:
@@ -281,16 +311,25 @@
   # Project loading:
 
   # Build recepy:
+  def buildFile(self):
+     ce = self.activeMdiChild()
+     if ce:
+        source = ce.source
+        self.buildOutput.clear()
+        self.buildOutput.append(str(self.compiler))
+        print(source)
+        self.compiler.compilesource(source)
+        self.buildOutput.append("Done!")
   def buildProject(self):
      """ Build project """
      self.buildOutput.clear()
      self.buildOutput.append(str(self.compiler))
      mods = self.compiler.compileProject(self.project)
 
-     self.builderrors.setErrorList(self.compiler.errorlist)
+     #self.builderrors.setErrorList(self.compiler.errorlist)
      self.astViewer.setAst(mods[0])
-     for err in self.compiler.errorlist:
-        self.buildOutput.append(str(err))
+     #for err in self.compiler.errorlist:
+     #   self.buildOutput.append(str(err))
      self.buildOutput.append("Done!")
 
 if __name__ == '__main__':
--- a/python/ppci/compilers/kscompiler.py	Mon Dec 24 16:35:22 2012 +0100
+++ b/python/ppci/compilers/kscompiler.py	Mon Dec 24 17:55:08 2012 +0100
@@ -3,9 +3,9 @@
 from ..frontends.ks import KsParser
 #from .codegenerator import CodeGenerator
 #from .nodes import ExportedSymbol
-#from .errors import CompilerException
+from ..core.errors import CompilerException
+from ..core import version
 #from .. import version
-version='0.0.1'
 
 class KsCompiler:
    def __repr__(self):
@@ -18,16 +18,19 @@
       """ Front end that handles the stages: """
       self.errorlist = []
       # Pass 1: parsing and type checking
-      tokens = lexer.tokenize(src) # Lexical stage
-      p = Parser(tokens)
+      p = KsParser(src)
       try:
-         ast = p.parseModule() # Parse a module
+         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
-      # Pass 2: code generation
+      # pass 2: Optimization
+      # TODO: implement optimization
+
+      # Pass 3: code generation
       CodeGenerator().generatecode(ast)
       # Attach a signature:
       ast.signature = self.generateSignature(src)
--- a/python/ppci/core/__init__.py	Mon Dec 24 16:35:22 2012 +0100
+++ b/python/ppci/core/__init__.py	Mon Dec 24 17:55:08 2012 +0100
@@ -4,3 +4,6 @@
 from .bitreader import BitReader
 from .errors import CompilerException
 
+
+version='0.0.1'
+
--- a/python/ppci/display.py	Mon Dec 24 16:35:22 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-from .nodes import *
-
-def printNode(node, indent=0):
-     """
-      Print visitor
-        all printing goes in here
-     """
-     print(' '*indent+str(node))
-     if type(node) is Procedure:
-       print(' '*indent+'  PARAMETERS:')
-       for p in node.parameters:
-         printNode(p, indent+4)
-       if node.block:
-         print(' '*indent+'  CODE:')
-         printNode(node.block, indent+4)
-     elif type(node) is Module:
-       print(node.symtable)
-       printNode(node.initcode, indent+2)
-     else:
-       for c in node.getChildren():
-         printNode(c, indent+2)
--- a/python/ppci/frontends/ks/__init__.py	Mon Dec 24 16:35:22 2012 +0100
+++ b/python/ppci/frontends/ks/__init__.py	Mon Dec 24 17:55:08 2012 +0100
@@ -1,10 +1,12 @@
-
 """
  Frontend for the K# language.
 
  This module can parse K# code and create LLVM intermediate code.
-
 """
 
 from .parser import KsParser
 
+class KsFrontend:
+   def __init__(self):
+      pass
+
--- a/python/ppci/frontends/ks/lexer.py	Mon Dec 24 16:35:22 2012 +0100
+++ b/python/ppci/frontends/ks/lexer.py	Mon Dec 24 17:55:08 2012 +0100
@@ -1,6 +1,5 @@
-import collections
-import re
-from .errors import CompilerException
+import collections, re
+from ...core.errors import CompilerException
 
 """
  Lexical analyzer part. Splits the input character stream into tokens.
--- a/python/ppci/frontends/ks/nodes.py	Mon Dec 24 16:35:22 2012 +0100
+++ b/python/ppci/frontends/ks/nodes.py	Mon Dec 24 17:55:08 2012 +0100
@@ -1,6 +1,7 @@
 """
-Parse tree elements
+AST nodes for the K# language.
 """
+
 class Node:
    location = None
    def getChildren(self):
--- a/python/ppci/frontends/ks/parser.py	Mon Dec 24 16:35:22 2012 +0100
+++ b/python/ppci/frontends/ks/parser.py	Mon Dec 24 17:55:08 2012 +0100
@@ -5,15 +5,14 @@
 from .symboltable import SymbolTable
 from .nodes import *
 from ...core.errors import CompilerException, Error
-#from .modules import loadModule
-#from .display import printNode
 #from .builtin import *
 #from . import assembler
+from .lexer import tokenize
 
 class KsParser:
-   def __init__(self, tokens):
+   def __init__(self, source):
       """ provide the parser with the tokens iterator from the lexer. """
-      self.tokens = tokens
+      self.tokens = tokenize(source) # Lexical stage
       self.NextToken()
       self.errorlist = []
 
@@ -53,6 +52,7 @@
         Starting symbol is the Module.
    """
    def parseModule(self):
+       """ Top level parsing routine """
        self.imports = []
        loc = self.getLocation()
        self.Consume('module')
@@ -98,7 +98,7 @@
    def parseImport(self):
       loc = self.getLocation()
       modname = self.Consume('ID')
-      mod = loadModule(modname)
+      #mod = loadModule(modname)
       self.setLocation(mod, loc)
       self.cst.addSymbol(mod)