diff --git a/examples/invalid.flx b/examples/invalid.flx new file mode 100644 index 0000000..b6f21f0 --- /dev/null +++ b/examples/invalid.flx @@ -0,0 +1,4 @@ +fn main() { + let a : 12 = 3; + return -; +} \ No newline at end of file diff --git a/fluxc/Cargo.lock b/fluxc/Cargo.lock index d867fb8..984f744 100644 --- a/fluxc/Cargo.lock +++ b/fluxc/Cargo.lock @@ -7,6 +7,7 @@ name = "fluxc" version = "0.1.0" dependencies = [ "unicode-xid", + "yansi", ] [[package]] @@ -14,3 +15,9 @@ name = "unicode-xid" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" diff --git a/fluxc/Cargo.toml b/fluxc/Cargo.toml index a00b335..993a656 100644 --- a/fluxc/Cargo.toml +++ b/fluxc/Cargo.toml @@ -5,3 +5,4 @@ edition = "2024" [dependencies] unicode-xid = "0.2" +yansi = "1" diff --git a/fluxc/src/diagnostics.rs b/fluxc/src/diagnostics.rs new file mode 100644 index 0000000..6e8c67b --- /dev/null +++ b/fluxc/src/diagnostics.rs @@ -0,0 +1,323 @@ +use std::fmt::Write as _; + +use yansi::{Color, Paint as _}; + +use crate::token::Span; + +// ── Level ────────────────────────────────────────────────────────────────────── + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Level { + Critical, + Error, + Warning, + Note, +} + +impl Level { + fn label_str(self) -> &'static str { + match self { + Level::Critical => "critical", + Level::Error => "error", + Level::Warning => "warning", + Level::Note => "note", + } + } + + fn color(self) -> Color { + match self { + Level::Critical => Color::Magenta, + Level::Error => Color::Red, + Level::Warning => Color::Yellow, + Level::Note => Color::Cyan, + } + } +} + +// ── Label ────────────────────────────────────────────────────────────────────── + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum LabelStyle { + Primary, + Secondary, +} + +#[derive(Debug, Clone)] +pub struct Label { + pub span: Span, + pub message: Option, + pub style: LabelStyle, +} + +impl Label { + pub fn primary(span: Span) -> Self { + Self { + span, + message: None, + style: LabelStyle::Primary, + } + } + + pub fn secondary(span: Span) -> Self { + Self { + span, + message: None, + style: LabelStyle::Secondary, + } + } + + pub fn with_message(mut self, msg: impl Into) -> Self { + self.message = Some(msg.into()); + self + } +} + +// ── Diagnostic ───────────────────────────────────────────────────────────────── + +#[derive(Debug, Clone)] +pub struct Diagnostic { + pub level: Level, + pub message: String, + pub labels: Vec