38 lines
1.2 KiB
Python
38 lines
1.2 KiB
Python
from __future__ import annotations
|
|
|
|
import inspect
|
|
|
|
from . import source, lexer
|
|
|
|
|
|
class CompilationError(Exception):
|
|
def __init__(self, location: source.SourceLocation, message: str = "Unknown error"):
|
|
super().__init__(f"{message} at {str(location)}")
|
|
self.location = location
|
|
|
|
|
|
class UnexpectedTokenError(CompilationError):
|
|
def __init__(self, got: lexer.Token, wanted: lexer.Tokens | str):
|
|
message = wanted
|
|
if type(wanted) == lexer.Tokens:
|
|
message = str(wanted)
|
|
super().__init__(got.loc, f"Unexpected token '{got}', wanted {message}")
|
|
|
|
|
|
class SemanticAnalysisError(CompilationError):
|
|
pass
|
|
|
|
|
|
class OverrideMandatoryError(NotImplementedError):
|
|
def __init__(self, klass: object = None, function_name: str = None):
|
|
if klass is None or function_name is None:
|
|
frame = inspect.currentframe()
|
|
assert frame is not None
|
|
prev_frame = frame.f_back
|
|
assert prev_frame is not None
|
|
if klass is None:
|
|
klass = prev_frame.f_locals.get("self", None)
|
|
if function_name is None:
|
|
function_name = prev_frame.f_code.co_name
|
|
|
|
super().__init__(f"Please override {klass.__class__.__name__}.{function_name}")
|