From 5895c3aa6552f75d7e5202be561f9734fe8945e7 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 13 Aug 2019 19:31:23 +0200 Subject: No need to track the absence of `Span`s at the type level --- dhall_syntax/src/core/expr.rs | 131 +++++++++++++++++++-------------------- dhall_syntax/src/core/visitor.rs | 40 ++++-------- dhall_syntax/src/parser.rs | 39 ++---------- dhall_syntax/src/printer.rs | 12 ++-- 4 files changed, 84 insertions(+), 138 deletions(-) (limited to 'dhall_syntax') 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(x: Result) -> T { } } +/// A location in the source text +#[derive(Debug, Clone)] +pub struct Span { + input: Rc, + /// # 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, 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; -pub type ResolvedExpr = SubExpr; -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(Rc<(Expr, Option)>); +pub struct SubExpr(Rc<(Expr, Option)>); -impl std::cmp::PartialEq for SubExpr { +impl std::cmp::PartialEq for SubExpr { fn eq(&self, other: &Self) -> bool { self.0.as_ref().0 == other.0.as_ref().0 } } -impl std::cmp::Eq for SubExpr {} +impl std::cmp::Eq for SubExpr {} -pub type Expr = ExprF, Embed>; +pub type Expr = ExprF, Embed>; /// Syntax tree for expressions // Having the recursion out of the enum definition enables writing @@ -293,31 +313,22 @@ impl ExprF { } } -impl Expr { +impl Expr { fn traverse_embed( &self, visit_embed: impl FnMut(&E) -> Result, - ) -> Result, Err> - where - N: Clone, - { + ) -> Result, Err> { self.visit(&mut visitor::TraverseEmbedVisitor(visit_embed)) } - fn map_embed(&self, mut map_embed: impl FnMut(&E) -> E2) -> Expr - where - N: Clone, - { + fn map_embed(&self, mut map_embed: impl FnMut(&E) -> E2) -> Expr { trivial_result(self.traverse_embed(|x| Ok(map_embed(x)))) } pub fn traverse_resolve( &self, visit_embed: impl FnMut(&E) -> Result, - ) -> Result, Err> - where - N: Clone, - { + ) -> Result, Err> { self.traverse_resolve_with_visitor(&mut visitor::ResolveVisitor( visit_embed, )) @@ -326,9 +337,8 @@ impl Expr { pub(crate) fn traverse_resolve_with_visitor( &self, visitor: &mut visitor::ResolveVisitor, - ) -> Result, Err> + ) -> Result, Err> where - N: Clone, F1: FnMut(&E) -> Result, { match self { @@ -341,59 +351,44 @@ impl Expr { } } -impl Expr { - pub fn absurd(&self) -> Expr { +impl Expr { + pub fn absurd(&self) -> Expr { self.visit(&mut visitor::AbsurdVisitor) } } -impl Expr { - pub fn note_absurd(&self) -> Expr { - self.visit(&mut visitor::NoteAbsurdVisitor) - } -} - -impl SubExpr { - pub fn as_ref(&self) -> &Expr { +impl SubExpr { + pub fn as_ref(&self) -> &Expr { &self.0.as_ref().0 } - pub fn new(x: Expr, n: N) -> Self { + pub fn new(x: Expr, n: Span) -> Self { SubExpr(Rc::new((x, Some(n)))) } - pub fn from_expr_no_note(x: Expr) -> Self { + pub fn from_expr_no_span(x: Expr) -> 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(&self, x: Expr) -> SubExpr - where - N: Clone, - { + pub fn rewrap(&self, x: Expr) -> SubExpr { SubExpr(Rc::new((x, (self.0).1.clone()))) } pub fn traverse_embed( &self, visit_embed: impl FnMut(&E) -> Result, - ) -> Result, Err> - where - N: Clone, - { + ) -> Result, Err> { Ok(self.rewrap(self.as_ref().traverse_embed(visit_embed)?)) } pub fn map_embed( &self, map_embed: impl FnMut(&E) -> E2, - ) -> SubExpr - where - N: Clone, - { + ) -> SubExpr { self.rewrap(self.as_ref().map_embed(map_embed)) } @@ -401,10 +396,7 @@ impl SubExpr { &'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 SubExpr { pub fn traverse_resolve( &self, visit_embed: impl FnMut(&E) -> Result, - ) -> Result, Err> - where - N: Clone, - { + ) -> Result, Err> { Ok(self.rewrap(self.as_ref().traverse_resolve(visit_embed)?)) } } -impl SubExpr { - pub fn absurd(&self) -> SubExpr { - SubExpr::from_expr_no_note(self.as_ref().absurd()) - } -} - -impl SubExpr { - pub fn note_absurd(&self) -> SubExpr { - SubExpr::from_expr_no_note(self.as_ref().note_absurd()) +impl SubExpr { + pub fn absurd(&self) -> SubExpr { + SubExpr::from_expr_no_span(self.as_ref().absurd()) } } -impl Clone for SubExpr { +impl Clone for SubExpr { fn clone(&self) -> Self { SubExpr(Rc::clone(&self.0)) } } // Should probably rename this -pub fn rc(x: Expr) -> SubExpr { - SubExpr::from_expr_no_note(x) +pub fn rc(x: Expr) -> SubExpr { + 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(pub F1); -impl<'a, 'b, N, E, E2, Err, F1> - ExprFFallibleVisitor<'a, SubExpr, SubExpr, E, E2> +impl<'a, 'b, E, E2, Err, F1> + ExprFFallibleVisitor<'a, SubExpr, SubExpr, E, E2> for &'b mut TraverseEmbedVisitor where - N: Clone + 'a, F1: FnMut(&E) -> Result, { type Error = Err; fn visit_subexpr( &mut self, - subexpr: &'a SubExpr, - ) -> Result, Self::Error> { + subexpr: &'a SubExpr, + ) -> Result, Self::Error> { Ok(subexpr.rewrap(subexpr.as_ref().visit(&mut **self)?)) } fn visit_embed(self, embed: &'a E) -> Result { @@ -358,19 +357,18 @@ where pub struct ResolveVisitor(pub F1); -impl<'a, 'b, N, E, E2, Err, F1> - ExprFFallibleVisitor<'a, SubExpr, SubExpr, E, E2> +impl<'a, 'b, E, E2, Err, F1> + ExprFFallibleVisitor<'a, SubExpr, SubExpr, E, E2> for &'b mut ResolveVisitor where - N: Clone + 'a, F1: FnMut(&E) -> Result, { type Error = Err; fn visit_subexpr( &mut self, - subexpr: &'a SubExpr, - ) -> Result, Self::Error> { + subexpr: &'a SubExpr, + ) -> Result, 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, SubExpr, E, E> - for &'b mut NoteAbsurdVisitor -where - E: Clone + 'a, -{ - fn visit_subexpr(&mut self, subexpr: &'a SubExpr) -> SubExpr { - 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, SubExpr, X, E> +impl<'a, 'b, E> ExprFInFallibleVisitor<'a, SubExpr, SubExpr, X, E> for &'b mut AbsurdVisitor { - fn visit_subexpr(&mut self, subexpr: &'a SubExpr) -> SubExpr { - SubExpr::from_expr_no_note(subexpr.as_ref().visit(&mut **self)) + fn visit_subexpr(&mut self, subexpr: &'a SubExpr) -> SubExpr { + 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; -type ParsedSubExpr = SubExpr; -type ParsedText = InterpolatedText>; -type ParsedTextContents = InterpolatedTextContents>; +pub(crate) type ParsedExpr = Expr; +pub(crate) type ParsedSubExpr = SubExpr; +type ParsedText = InterpolatedText>; +type ParsedTextContents = InterpolatedTextContents>; pub type ParseError = pest::error::Error; pub type ParseResult = Result; -fn unspanned(x: ParsedExpr) -> ParsedSubExpr { - SubExpr::from_expr_no_note(x) -} - -#[derive(Debug, Clone)] -pub struct Span { - input: Rc, - /// # 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, 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 { 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, PrintPhase); +struct PhasedExpr<'a, A>(&'a SubExpr, 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 Expr { +impl Expr { fn fmt_phase( &self, f: &mut fmt::Formatter, @@ -196,7 +196,7 @@ impl Expr { } } -impl Display for SubExpr { +impl Display for SubExpr { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { self.as_ref().fmt_phase(f, PrintPhase::Base) } -- cgit v1.2.3