errors: use termcolor for terminal output coloring + enable raising non-fatal errors

This commit is contained in:
Antoine Viallon 2024-01-06 00:17:47 +01:00
parent cd42fac98e
commit 8b0ec8cbe2
Signed by: aviallon
GPG key ID: 186FC35EDEB25716

View file

@ -1,29 +1,57 @@
from __future__ import annotations from __future__ import annotations
import enum
import inspect import inspect
import sys import sys
from typing import TextIO
from termcolor import termcolor
from . import source, lexer from . import source, lexer
class LevelType:
def __init__(self, name: str, color: termcolor.Color = None):
"""
:param name:
:param color: ANSI style color escapes without the prefix nor the suffix
"""
self.name = name
self.color = color
def __str__(self) -> str:
return self.show_with_suffix()
def show_with_suffix(self, suffix=":") -> str:
return termcolor.colored(f"{self.name}{suffix}", color=self.color, attrs=["bold"])
class Levels(enum.Enum):
Warning = LevelType("warning", color="light_yellow")
Error = LevelType("error", color="red")
class CompilationError(Exception): class CompilationError(Exception):
def __init__(self, location: source.SourceLocation, message: str = "Unknown error"): def __init__(self, location: source.SourceLocation, message: str = "Unknown error"):
super().__init__(f"{str(location)}: \033[1merror:\033[0m {message}") super().__init__(f"{str(location)}: {Levels.Error.value.show_with_suffix(':')} {message}")
self.location = location self.location = location
class CompilationWarning(Warning): class CompilationWarning(Warning):
_pending_warnings: list[CompilationWarning] = [] _pending_warnings: list[CompilationWarning] = []
def __init__(self, location: source.SourceLocation, message: str = "Unknown warning"): def __init__(self, location: source.SourceLocation, message: str = "Unknown warning",
super().__init__(f"{str(location)}: \033[1mwarning:\033[0m {message}") level: Levels = Levels.Warning):
super().__init__(f"{str(location)}: {level.value.show_with_suffix(':')} {message}")
self.location = location self.location = location
@classmethod @classmethod
def show_warnings(cls, _source: str): def show_warnings(cls, _source: str, file: TextIO = sys.stderr):
for warning in CompilationWarning._pending_warnings: for warning in CompilationWarning._pending_warnings:
warning.location.source = _source warning.location.source = _source
print(f"{warning}\n{warning.location.show_in_source()}", file=sys.stderr) print(f"{warning}\n{warning.location.show_in_source()}", file=file)
def raise_warning(self): def raise_warning(self):
CompilationWarning._pending_warnings += [self] CompilationWarning._pending_warnings += [self]