// rasm-core/src/analysis/air/err.rs
//
//! Ошибки построения промежуточного представления (AIR).
use crate::{lexer::token::Span, str_pool::StrId};
use std::fmt::Display;

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AIRErrorKind {
    /// Переход (`jmp`, `je`, ..., `call`) ссылается на метку, которой нет
    /// нигде в программе. Это ошибка, а не варнинг: код гарантированно
    /// неисполним в этой точке.
    ///
    /// Дублирующиеся метки сюда не входят — это AST-уровневая находка
    /// (см. `ASTAnalyseErrorVariant::DuplicateLabel`), не требующая графа.
    UnknownLabel(StrId),
}

impl Display for AIRErrorKind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::UnknownLabel(_) => write!(f, "jump target refers to an undefined label"),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AIRError {
    pub kind: AIRErrorKind,
    pub pos: Span,
}

impl AIRError {
    pub fn new(kind: AIRErrorKind, pos: Span) -> Self {
        Self { kind, pos }
    }
}

impl Display for AIRError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.kind)
    }
}
