aboutsummaryrefslogtreecommitdiffstats
path: root/src/parse/span.rs
diff options
context:
space:
mode:
authorJonas Maier <jonas@x77.dev>2026-05-22 21:26:41 +0200
committerJonas Maier <jonas@x77.dev>2026-05-22 21:26:41 +0200
commiteeb267c46340d5d47f41cc2440f0b281f9ae9261 (patch)
treeabcbc6624e0903cc1c7cd919d15a42ebb970692a /src/parse/span.rs
parent07daff9331dbdc607584edbf1a8fb3e415c338ea (diff)
downloadpish-eeb267c46340d5d47f41cc2440f0b281f9ae9261.tar.gz
basic syntax highlighting
Diffstat (limited to 'src/parse/span.rs')
-rw-r--r--src/parse/span.rs86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/parse/span.rs b/src/parse/span.rs
new file mode 100644
index 0000000..340a078
--- /dev/null
+++ b/src/parse/span.rs
@@ -0,0 +1,86 @@
+use std::sync::atomic::AtomicU32;
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct FileId {
+ id: u32,
+}
+
+impl FileId {
+ pub fn new() -> Self {
+ static GEN: AtomicU32 = AtomicU32::new(0);
+ Self {
+ id: GEN.fetch_add(1, std::sync::atomic::Ordering::SeqCst),
+ }
+ }
+
+ pub fn from(self, start: u32) -> SpanFrom {
+ SpanFrom::new(self, start)
+ }
+
+ pub fn span(self, start: u32, end: u32) -> Span {
+ Span::new(self, start, end)
+ }
+}
+
+#[derive(Copy, Clone)]
+pub struct SpanFrom {
+ pub file: FileId,
+ pub start: u32,
+}
+
+impl SpanFrom {
+ pub fn new(file: FileId, start: u32) -> Self {
+ Self { file, start }
+ }
+
+ pub fn to(self, end: u32) -> Span {
+ Span::new(self.file, self.start, end)
+ }
+
+ pub fn with_len(self, len: u32) -> Span {
+ self.to(self.start + len)
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub struct Span {
+ pub file: FileId,
+ pub start: u32,
+ pub end: u32,
+}
+
+/// manual implementation of PartialOrd to ensure shorter Spans are first
+impl PartialOrd for Span {
+ fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+ match self.file.partial_cmp(&other.file) {
+ Some(core::cmp::Ordering::Equal) => {}
+ ord => return ord,
+ }
+ match self.start.partial_cmp(&other.start) {
+ Some(core::cmp::Ordering::Equal) => {}
+ ord => return ord,
+ }
+ other.end.partial_cmp(&self.end)
+ }
+}
+
+/// manual implementation of Ord to ensure shorter Spans are first
+impl Ord for Span {
+ fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+ match self.file.cmp(&other.file) {
+ core::cmp::Ordering::Equal => {}
+ ord => return ord,
+ }
+ match self.start.cmp(&other.start) {
+ core::cmp::Ordering::Equal => {}
+ ord => return ord,
+ }
+ other.end.cmp(&self.end)
+ }
+}
+
+impl Span {
+ pub fn new(file: FileId, start: u32, end: u32) -> Self {
+ Self { file, start, end }
+ }
+}