From 9fb31defd037a90bf8f9e38fa33acae23a70b269 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Wed, 4 Dec 2019 19:34:29 +0100 Subject: =?UTF-8?q?Expand=20functionality=20of=20function!=20macro=20?= =?UTF-8?q?=F0=9F=9B=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/syntax/span.rs | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/syntax/span.rs (limited to 'src/syntax/span.rs') diff --git a/src/syntax/span.rs b/src/syntax/span.rs new file mode 100644 index 00000000..aa494224 --- /dev/null +++ b/src/syntax/span.rs @@ -0,0 +1,72 @@ +//! Spans map elements to the part of source code they originate from. + +use std::fmt::{self, Display, Formatter}; + +/// Annotates a value with the part of the source code it corresponds to. +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct Spanned { + pub val: T, + pub span: Span, +} + +impl Spanned { + pub fn new(val: T, span: Span) -> Spanned { + Spanned { val, span } + } + + pub fn value(self) -> T { + self.val + } + + pub fn span_map(self, f: F) -> Spanned where F: FnOnce(T) -> U { + Spanned::new(f(self.val), self.span) + } +} + +impl Display for Spanned where T: std::fmt::Debug { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "({:?}:{})", self.val, self.span) + } +} + +debug_display!(Spanned; T where T: std::fmt::Debug); + +/// Describes a slice of source code. +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct Span { + pub start: usize, + pub end: usize, +} + +impl Span { + pub fn new(start: usize, end: usize) -> Span { + Span { start, end } + } + + pub fn merge(a: Span, b: Span) -> Span { + Span { + start: a.start.min(b.start), + end: a.end.max(b.end), + } + } + + pub fn at(index: usize) -> Span { + Span { start: index, end: index + 1 } + } + + pub fn pair(&self) -> (usize, usize) { + (self.start, self.end) + } + + pub fn expand(&mut self, other: Span) { + *self = Span::merge(*self, other) + } +} + +impl Display for Span { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "[{}, {}]", self.start, self.end) + } +} + +debug_display!(Span); -- cgit v1.2.3