view python/ppci/errors.py @ 271:cf7d5fb7d9c8

Reorganization
author Windel Bouwman
date Tue, 20 Aug 2013 18:56:02 +0200
parents 7416c923a02a
children 4496cae24d7f
line wrap: on
line source

""" 
   Error handling routines 
   Diagnostic utils
"""

import logging
from . import SourceLocation

class CompilerError(Exception):
    def __init__(self, msg, loc=None):
        self.msg = msg
        self.loc = loc
        if loc:
            assert type(loc) is SourceLocation, '{0} must be SourceLocation'.format(type(loc))
            self.row = loc.row
            self.col = loc.col
        else:
            self.row = self.col = 0

    def __repr__(self):
        if self.row:
            return 'Compilererror: "{0}" at row {1}'.format(self.msg, self.row)
        else:
            return 'Compilererror: "{0}"'.format(self.msg)

def printError(source, e):
    def printLine(row, txt):
        print(str(row)+':'+txt)
    if e.row == 0:
            print('Error: {0}'.format(e.msg))
    else:
        lines = source.split('\n')
        ro, co = e.row, e.col
        prerow = ro - 2
        if prerow < 1:
           prerow = 1
        afterrow = ro + 3
        if afterrow > len(lines):
           afterrow = len(lines)

        # print preceding source lines:
        for r in range(prerow, ro):
           printLine(r, lines[r-1])
        # print source line containing error:
        printLine(ro, lines[ro-1])
        print(' '*(len(str(ro)+':')+co-1) + '^ Error: {0}'.format(e.msg))
        # print trailing source line:
        for r in range(ro+1, afterrow+1):
          printLine(r, lines[r-1])

class DiagnosticsManager:
    def __init__(self):
        self.diags = []
        self.logger = logging.getLogger('diagnostics')

    def addDiag(self, d):
        self.logger.info(str(d))
        self.diags.append(d)

    def error(self, msg, loc):
        self.addDiag(CompilerError(msg, loc))

    def clear(self):
        del self.diags[:]

    def printErrors(self, src):
        if len(self.diags) > 0:
            print('==============')
            print('{0} Errors'.format(len(self.diags)))
            for d in self.diags:
                print('==============')
                printError(src, d)
            print('==============')