# HG changeset patch # User windel-eee # Date 1316706271 -7200 # Node ID 818f80afa78bd8cfd53c4e3581c3351cc26d3cfb # Parent 0d5ef85b86986d735b5a5103926883da1d5f7a60 Added handy highlighting to IDE diff -r 0d5ef85b8698 -r 818f80afa78b ide/compiler/codegenerator.py --- a/ide/compiler/codegenerator.py Wed Sep 21 19:05:18 2011 +0200 +++ b/ide/compiler/codegenerator.py Thu Sep 22 17:44:31 2011 +0200 @@ -312,7 +312,6 @@ elif isinstance(node, StatementSequence): for s in node.statements: self.gencode(s) - assert(len(self.usedregs) == 0) elif type(node) is ProcedureCall: # Prepare parameters on the stack: diff -r 0d5ef85b8698 -r 818f80afa78b ide/compiler/compiler.py --- a/ide/compiler/compiler.py Wed Sep 21 19:05:18 2011 +0200 +++ b/ide/compiler/compiler.py Thu Sep 22 17:44:31 2011 +0200 @@ -1,7 +1,7 @@ import hashlib # Import compiler components: from . import lexer -from . import parser +from .parser import Parser from .codegenerator import CodeGenerator from .nodes import ExportedSymbol @@ -16,8 +16,15 @@ def compilesource(self, src): """ Front end that handles the stages: """ + # Pass 1: parsing and type checking tokens = lexer.tokenize(src) # Lexical stage - ast = parser.Parser(tokens).parseModule() # Parse a module + p = Parser(tokens) + ast = p.parseModule() # Parse a module + print(p.errorlist) + if len(p.errorlist) > 0: + self.errorlist = p.errorlist + return + # Pass 2: code generation CodeGenerator().generatecode(ast) # Attach a signature: ast.signature = self.generateSignature(src) diff -r 0d5ef85b8698 -r 818f80afa78b ide/compiler/parser.py --- a/ide/compiler/parser.py Wed Sep 21 19:05:18 2011 +0200 +++ b/ide/compiler/parser.py Thu Sep 22 17:44:31 2011 +0200 @@ -2,7 +2,6 @@ This module parses source code into an abstract syntax tree (AST) """ -import shelve from .symboltable import SymbolTable from .nodes import * from .errors import CompilerException, Error @@ -16,6 +15,7 @@ """ provide the parser with the tokens iterator from the lexer. """ self.tokens = tokens self.NextToken() + self.errorlist = [] def Error(self, msg): raise CompilerException(msg, self.token.row, self.token.col) @@ -570,32 +570,37 @@ return AsmCode(asmcode) def parseStatement(self): - # Determine statement type based on the pending token: - if self.token.typ == 'if': - return self.parseIfStatement() - elif self.token.typ == 'case': - return self.parseCaseStatement() - elif self.token.typ == 'while': - return self.parseWhileStatement() - elif self.token.typ == 'repeat': - return self.parseRepeatStatement() - elif self.token.typ == 'for': - return self.parseForStatement() - elif self.token.typ == 'asm': - return self.parseAsmcode() - elif self.token.typ == 'ID': - # Assignment or procedure call - designator = self.parseDesignator() - if self.token.typ == '(' and type(designator.typ) is ProcedureType: - return self.parseProcedureCall(designator) - elif self.token.typ == ':=': - return self.parseAssignment(designator) + try: + # Determine statement type based on the pending token: + if self.token.typ == 'if': + return self.parseIfStatement() + elif self.token.typ == 'case': + return self.parseCaseStatement() + elif self.token.typ == 'while': + return self.parseWhileStatement() + elif self.token.typ == 'repeat': + return self.parseRepeatStatement() + elif self.token.typ == 'for': + return self.parseForStatement() + elif self.token.typ == 'asm': + return self.parseAsmcode() + elif self.token.typ == 'ID': + # Assignment or procedure call + designator = self.parseDesignator() + if self.token.typ == '(' and type(designator.typ) is ProcedureType: + return self.parseProcedureCall(designator) + elif self.token.typ == ':=': + return self.parseAssignment(designator) + else: + self.Error('Unknown statement following designator: {0}'.format(self.token)) else: - self.Error('Unknown statement following designator: {0}'.format(self.token)) - else: - # TODO: return empty statement??: - return EmptyStatement() - self.Error('Unknown statement {0}'.format(self.token)) + # TODO: return empty statement??: + return EmptyStatement() + self.Error('Unknown statement {0}'.format(self.token)) + except CompilerException as e: + print(e) + self.errorlist.append( (e.row, e.col, e.msg)) + return EmptyStatement() def parseStatementSequence(self): """ Sequence of statements seperated by ';' """ diff -r 0d5ef85b8698 -r 818f80afa78b ide/ide/ide.py --- a/ide/ide/ide.py Wed Sep 21 19:05:18 2011 +0200 +++ b/ide/ide/ide.py Thu Sep 22 17:44:31 2011 +0200 @@ -9,6 +9,12 @@ module x; var a,b,c : integer; +procedure test(x:integer); + var y,z:integer; +begin + y := x * 3 + 2; + z := x + y + a; +end test; begin a := 12; b := a * 12 + 33; @@ -26,6 +32,13 @@ self.setReadOnly(True) self.append('Build output will appear here!') +class BuildErrors(QListWidget): + def __init__(self, parent=None): + super(BuildErrors, self).__init__(parent) + item = QListWidgetItem('Hallo dan!') + self.addItem(item) + + class Ide(QMainWindow): def __init__(self, parent=None): super(Ide, self).__init__(parent) @@ -49,6 +62,9 @@ self.addComponent('AST viewer', self.astViewer) self.astViewer.sigNodeSelected.connect(self.nodeSelected) + self.builderrors = BuildErrors() + self.addComponent('Build errors', self.builderrors) + # Create actions: self.buildAction = QAction('Build!', self) self.buildAction.setShortcut(QKeySequence('F7')) @@ -70,6 +86,7 @@ dw.setObjectName(name) self.addDockWidget(Qt.RightDockWidgetArea, dw) self.viewMenu.addAction(dw.toggleViewAction()) + def loadSettings(self): if self.settings.contains('mainwindowstate'): self.restoreState(self.settings.value('mainwindowstate')) diff -r 0d5ef85b8698 -r 818f80afa78b ide/runtests.py --- a/ide/runtests.py Wed Sep 21 19:05:18 2011 +0200 +++ b/ide/runtests.py Thu Sep 22 17:44:31 2011 +0200 @@ -92,7 +92,7 @@ """ pc = Compiler() pc.compilesource(source) - def testForStatement(self): + def tstForStatement(self): source = """ module fortest; var