summaryrefslogtreecommitdiff
path: root/dhall_syntax
diff options
context:
space:
mode:
authorNadrieril2019-08-13 19:31:23 +0200
committerNadrieril2019-08-13 19:31:23 +0200
commit5895c3aa6552f75d7e5202be561f9734fe8945e7 (patch)
tree80c4258ce94e82af29bf6a09f483c38601a16b34 /dhall_syntax
parentcbd62bb57bcc94e0133c57437488a5af22a0b1c2 (diff)
No need to track the absence of `Span`s at the type level
Diffstat (limited to '')
-rw-r--r--dhall_syntax/src/core/expr.rs131
-rw-r--r--dhall_syntax/src/core/visitor.rs40
-rw-r--r--dhall_syntax/src/parser.rs39
-rw-r--r--dhall_syntax/src/printer.rs12
4 files changed, 84 insertions, 138 deletions
diff --git a/dhall_syntax/src/core/expr.rs b/dhall_syntax/src/core/expr.rs
index 6522cb1..0cbece3 100644
--- a/dhall_syntax/src/core/expr.rs
+++ b/dhall_syntax/src/core/expr.rs
@@ -19,6 +19,30 @@ pub fn trivial_result<T>(x: Result<T, X>) -> T {
}
}
+/// A location in the source text
+#[derive(Debug, Clone)]
+pub struct Span {
+ input: Rc<str>,
+ /// # Safety
+ ///
+ /// Must be a valid character boundary index into `input`.
+ start: usize,
+ /// # Safety
+ ///
+ /// Must be a valid character boundary index into `input`.
+ end: usize,
+}
+
+impl Span {
+ pub(crate) fn make(input: Rc<str>, sp: pest::Span) -> Self {
+ Span {
+ input,
+ start: sp.start(),
+ end: sp.end(),
+ }
+ }
+}
+
/// Double with bitwise equality
#[derive(Debug, Copy, Clone)]
pub struct NaiveDouble(f64);
@@ -137,23 +161,19 @@ pub enum Builtin {
TextShow,
}
-pub type ParsedExpr = SubExpr<X, Import>;
-pub type ResolvedExpr = SubExpr<X, X>;
-pub type DhallExpr = ResolvedExpr;
-
// Each node carries an annotation. In practice it's either X (no annotation) or a Span.
#[derive(Debug)]
-pub struct SubExpr<Note, Embed>(Rc<(Expr<Note, Embed>, Option<Note>)>);
+pub struct SubExpr<Embed>(Rc<(Expr<Embed>, Option<Span>)>);
-impl<Note, Embed: PartialEq> std::cmp::PartialEq for SubExpr<Note, Embed> {
+impl<Embed: PartialEq> std::cmp::PartialEq for SubExpr<Embed> {
fn eq(&self, other: &Self) -> bool {
self.0.as_ref().0 == other.0.as_ref().0
}
}
-impl<Note, Embed: Eq> std::cmp::Eq for SubExpr<Note, Embed> {}
+impl<Embed: Eq> std::cmp::Eq for SubExpr<Embed> {}
-pub type Expr<Note, Embed> = ExprF<SubExpr<Note, Embed>, Embed>;
+pub type Expr<Embed> = ExprF<SubExpr<Embed>, Embed>;
/// Syntax tree for expressions
// Having the recursion out of the enum definition enables writing
@@ -293,31 +313,22 @@ impl<SE, E> ExprF<SE, E> {
}
}
-impl<N, E> Expr<N, E> {
+impl<E> Expr<E> {
fn traverse_embed<E2, Err>(
&self,
visit_embed: impl FnMut(&E) -> Result<E2, Err>,
- ) -> Result<Expr<N, E2>, Err>
- where
- N: Clone,
- {
+ ) -> Result<Expr<E2>, Err> {
self.visit(&mut visitor::TraverseEmbedVisitor(visit_embed))
}
- fn map_embed<E2>(&self, mut map_embed: impl FnMut(&E) -> E2) -> Expr<N, E2>
- where
- N: Clone,
- {
+ fn map_embed<E2>(&self, mut map_embed: impl FnMut(&E) -> E2) -> Expr<E2> {
trivial_result(self.traverse_embed(|x| Ok(map_embed(x))))
}
pub fn traverse_resolve<E2, Err>(
&self,
visit_embed: impl FnMut(&E) -> Result<E2, Err>,
- ) -> Result<Expr<N, E2>, Err>
- where
- N: Clone,
- {
+ ) -> Result<Expr<E2>, Err> {
self.traverse_resolve_with_visitor(&mut visitor::ResolveVisitor(
visit_embed,
))
@@ -326,9 +337,8 @@ impl<N, E> Expr<N, E> {
pub(crate) fn traverse_resolve_with_visitor<E2, Err, F1>(
&self,
visitor: &mut visitor::ResolveVisitor<F1>,
- ) -> Result<Expr<N, E2>, Err>
+ ) -> Result<Expr<E2>, Err>
where
- N: Clone,
F1: FnMut(&E) -> Result<E2, Err>,
{
match self {
@@ -341,59 +351,44 @@ impl<N, E> Expr<N, E> {
}
}
-impl Expr<X, X> {
- pub fn absurd<N, E>(&self) -> Expr<N, E> {
+impl Expr<X> {
+ pub fn absurd<E>(&self) -> Expr<E> {
self.visit(&mut visitor::AbsurdVisitor)
}
}
-impl<E: Clone> Expr<X, E> {
- pub fn note_absurd<N>(&self) -> Expr<N, E> {
- self.visit(&mut visitor::NoteAbsurdVisitor)
- }
-}
-
-impl<N, E> SubExpr<N, E> {
- pub fn as_ref(&self) -> &Expr<N, E> {
+impl<E> SubExpr<E> {
+ pub fn as_ref(&self) -> &Expr<E> {
&self.0.as_ref().0
}
- pub fn new(x: Expr<N, E>, n: N) -> Self {
+ pub fn new(x: Expr<E>, n: Span) -> Self {
SubExpr(Rc::new((x, Some(n))))
}
- pub fn from_expr_no_note(x: Expr<N, E>) -> Self {
+ pub fn from_expr_no_span(x: Expr<E>) -> Self {
SubExpr(Rc::new((x, None)))
}
pub fn from_builtin(b: Builtin) -> Self {
- SubExpr::from_expr_no_note(ExprF::Builtin(b))
+ SubExpr::from_expr_no_span(ExprF::Builtin(b))
}
- pub fn rewrap<E2>(&self, x: Expr<N, E2>) -> SubExpr<N, E2>
- where
- N: Clone,
- {
+ pub fn rewrap<E2>(&self, x: Expr<E2>) -> SubExpr<E2> {
SubExpr(Rc::new((x, (self.0).1.clone())))
}
pub fn traverse_embed<E2, Err>(
&self,
visit_embed: impl FnMut(&E) -> Result<E2, Err>,
- ) -> Result<SubExpr<N, E2>, Err>
- where
- N: Clone,
- {
+ ) -> Result<SubExpr<E2>, Err> {
Ok(self.rewrap(self.as_ref().traverse_embed(visit_embed)?))
}
pub fn map_embed<E2>(
&self,
map_embed: impl FnMut(&E) -> E2,
- ) -> SubExpr<N, E2>
- where
- N: Clone,
- {
+ ) -> SubExpr<E2> {
self.rewrap(self.as_ref().map_embed(map_embed))
}
@@ -401,10 +396,7 @@ impl<N, E> SubExpr<N, E> {
&'a self,
map_expr: impl FnMut(&'a Self) -> Self,
map_under_binder: impl FnMut(&'a Label, &'a Self) -> Self,
- ) -> Self
- where
- N: Clone,
- {
+ ) -> Self {
match self.as_ref() {
ExprF::Embed(_) => SubExpr::clone(self),
// This calls ExprF::map_ref
@@ -419,35 +411,38 @@ impl<N, E> SubExpr<N, E> {
pub fn traverse_resolve<E2, Err>(
&self,
visit_embed: impl FnMut(&E) -> Result<E2, Err>,
- ) -> Result<SubExpr<N, E2>, Err>
- where
- N: Clone,
- {
+ ) -> Result<SubExpr<E2>, Err> {
Ok(self.rewrap(self.as_ref().traverse_resolve(visit_embed)?))
}
}
-impl SubExpr<X, X> {
- pub fn absurd<N: Clone, T>(&self) -> SubExpr<N, T> {
- SubExpr::from_expr_no_note(self.as_ref().absurd())
- }
-}
-
-impl<E: Clone> SubExpr<X, E> {
- pub fn note_absurd<N>(&self) -> SubExpr<N, E> {
- SubExpr::from_expr_no_note(self.as_ref().note_absurd())
+impl SubExpr<X> {
+ pub fn absurd<T>(&self) -> SubExpr<T> {
+ SubExpr::from_expr_no_span(self.as_ref().absurd())
}
}
-impl<N, E> Clone for SubExpr<N, E> {
+impl<E> Clone for SubExpr<E> {
fn clone(&self) -> Self {
SubExpr(Rc::clone(&self.0))
}
}
// Should probably rename this
-pub fn rc<E>(x: Expr<X, E>) -> SubExpr<X, E> {
- SubExpr::from_expr_no_note(x)
+pub fn rc<E>(x: Expr<E>) -> SubExpr<E> {
+ SubExpr::from_expr_no_span(x)
+}
+
+pub(crate) fn spanned(
+ span: Span,
+ x: crate::parser::ParsedExpr,
+) -> crate::parser::ParsedSubExpr {
+ SubExpr::new(x, span)
+}
+pub(crate) fn unspanned(
+ x: crate::parser::ParsedExpr,
+) -> crate::parser::ParsedSubExpr {
+ SubExpr::from_expr_no_span(x)
}
/// Add an isize to an usize
diff --git a/dhall_syntax/src/core/visitor.rs b/dhall_syntax/src/core/visitor.rs
index 18f76d9..50ec68a 100644
--- a/dhall_syntax/src/core/visitor.rs
+++ b/dhall_syntax/src/core/visitor.rs
@@ -336,19 +336,18 @@ where
pub struct TraverseEmbedVisitor<F1>(pub F1);
-impl<'a, 'b, N, E, E2, Err, F1>
- ExprFFallibleVisitor<'a, SubExpr<N, E>, SubExpr<N, E2>, E, E2>
+impl<'a, 'b, E, E2, Err, F1>
+ ExprFFallibleVisitor<'a, SubExpr<E>, SubExpr<E2>, E, E2>
for &'b mut TraverseEmbedVisitor<F1>
where
- N: Clone + 'a,
F1: FnMut(&E) -> Result<E2, Err>,
{
type Error = Err;
fn visit_subexpr(
&mut self,
- subexpr: &'a SubExpr<N, E>,
- ) -> Result<SubExpr<N, E2>, Self::Error> {
+ subexpr: &'a SubExpr<E>,
+ ) -> Result<SubExpr<E2>, Self::Error> {
Ok(subexpr.rewrap(subexpr.as_ref().visit(&mut **self)?))
}
fn visit_embed(self, embed: &'a E) -> Result<E2, Self::Error> {
@@ -358,19 +357,18 @@ where
pub struct ResolveVisitor<F1>(pub F1);
-impl<'a, 'b, N, E, E2, Err, F1>
- ExprFFallibleVisitor<'a, SubExpr<N, E>, SubExpr<N, E2>, E, E2>
+impl<'a, 'b, E, E2, Err, F1>
+ ExprFFallibleVisitor<'a, SubExpr<E>, SubExpr<E2>, E, E2>
for &'b mut ResolveVisitor<F1>
where
- N: Clone + 'a,
F1: FnMut(&E) -> Result<E2, Err>,
{
type Error = Err;
fn visit_subexpr(
&mut self,
- subexpr: &'a SubExpr<N, E>,
- ) -> Result<SubExpr<N, E2>, Self::Error> {
+ subexpr: &'a SubExpr<E>,
+ ) -> Result<SubExpr<E2>, Self::Error> {
Ok(subexpr.rewrap(
subexpr
.as_ref()
@@ -381,30 +379,14 @@ where
(self.0)(embed)
}
}
-pub struct NoteAbsurdVisitor;
-
-impl<'a, 'b, N, E>
- ExprFInFallibleVisitor<'a, SubExpr<X, E>, SubExpr<N, E>, E, E>
- for &'b mut NoteAbsurdVisitor
-where
- E: Clone + 'a,
-{
- fn visit_subexpr(&mut self, subexpr: &'a SubExpr<X, E>) -> SubExpr<N, E> {
- SubExpr::from_expr_no_note(subexpr.as_ref().visit(&mut **self))
- }
- fn visit_embed(self, embed: &'a E) -> E {
- E::clone(embed)
- }
-}
pub struct AbsurdVisitor;
-impl<'a, 'b, N, E>
- ExprFInFallibleVisitor<'a, SubExpr<X, X>, SubExpr<N, E>, X, E>
+impl<'a, 'b, E> ExprFInFallibleVisitor<'a, SubExpr<X>, SubExpr<E>, X, E>
for &'b mut AbsurdVisitor
{
- fn visit_subexpr(&mut self, subexpr: &'a SubExpr<X, X>) -> SubExpr<N, E> {
- SubExpr::from_expr_no_note(subexpr.as_ref().visit(&mut **self))
+ fn visit_subexpr(&mut self, subexpr: &'a SubExpr<X>) -> SubExpr<E> {
+ SubExpr::from_expr_no_span(subexpr.as_ref().visit(&mut **self))
}
fn visit_embed(self, embed: &'a X) -> E {
match *embed {}
diff --git a/dhall_syntax/src/parser.rs b/dhall_syntax/src/parser.rs
index 9ae6dc8..1ab6e6d 100644
--- a/dhall_syntax/src/parser.rs
+++ b/dhall_syntax/src/parser.rs
@@ -15,46 +15,15 @@ use crate::*;
// their own crate because they are quite general and useful. For now they
// are here and hopefully you can figure out how they work.
-type ParsedExpr = Expr<Span, Import>;
-type ParsedSubExpr = SubExpr<Span, Import>;
-type ParsedText = InterpolatedText<SubExpr<Span, Import>>;
-type ParsedTextContents = InterpolatedTextContents<SubExpr<Span, Import>>;
+pub(crate) type ParsedExpr = Expr<Import>;
+pub(crate) type ParsedSubExpr = SubExpr<Import>;
+type ParsedText = InterpolatedText<SubExpr<Import>>;
+type ParsedTextContents = InterpolatedTextContents<SubExpr<Import>>;
pub type ParseError = pest::error::Error<Rule>;
pub type ParseResult<T> = Result<T, ParseError>;
-fn unspanned(x: ParsedExpr) -> ParsedSubExpr {
- SubExpr::from_expr_no_note(x)
-}
-
-#[derive(Debug, Clone)]
-pub struct Span {
- input: Rc<str>,
- /// # Safety
- ///
- /// Must be a valid character boundary index into `input`.
- start: usize,
- /// # Safety
- ///
- /// Must be a valid character boundary index into `input`.
- end: usize,
-}
-
-impl Span {
- fn make(input: Rc<str>, sp: pest::Span) -> Self {
- Span {
- input,
- start: sp.start(),
- end: sp.end(),
- }
- }
-}
-
-fn spanned(span: Span, x: ParsedExpr) -> ParsedSubExpr {
- SubExpr::new(x, span)
-}
-
#[derive(Debug)]
enum Either<A, B> {
Left(A),
diff --git a/dhall_syntax/src/printer.rs b/dhall_syntax/src/printer.rs
index 70b224e..95eafe5 100644
--- a/dhall_syntax/src/printer.rs
+++ b/dhall_syntax/src/printer.rs
@@ -111,21 +111,21 @@ enum PrintPhase {
// Wraps an Expr with a phase, so that phase selsction can be done
// separate from the actual printing
#[derive(Clone)]
-struct PhasedExpr<'a, S, A>(&'a SubExpr<S, A>, PrintPhase);
+struct PhasedExpr<'a, A>(&'a SubExpr<A>, PrintPhase);
-impl<'a, S: Clone, A: Display + Clone> Display for PhasedExpr<'a, S, A> {
+impl<'a, A: Display + Clone> Display for PhasedExpr<'a, A> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.0.as_ref().fmt_phase(f, self.1)
}
}
-impl<'a, S: Clone, A: Display + Clone> PhasedExpr<'a, S, A> {
- fn phase(self, phase: PrintPhase) -> PhasedExpr<'a, S, A> {
+impl<'a, A: Display + Clone> PhasedExpr<'a, A> {
+ fn phase(self, phase: PrintPhase) -> PhasedExpr<'a, A> {
PhasedExpr(self.0, phase)
}
}
-impl<S: Clone, A: Display + Clone> Expr<S, A> {
+impl<A: Display + Clone> Expr<A> {
fn fmt_phase(
&self,
f: &mut fmt::Formatter,
@@ -196,7 +196,7 @@ impl<S: Clone, A: Display + Clone> Expr<S, A> {
}
}
-impl<S: Clone, A: Display + Clone> Display for SubExpr<S, A> {
+impl<A: Display + Clone> Display for SubExpr<A> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.as_ref().fmt_phase(f, PrintPhase::Base)
}