From bb1f698c23a83f60020a72bb5be1f9a386c60d44 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 18 Apr 2019 11:58:21 +0200 Subject: Start cleaning up the mess of mapping functions --- dhall_core/src/core.rs | 111 +++++++++++++++++++++++++++++++++++++--------- dhall_core/src/visitor.rs | 42 +++++++++++++++++- 2 files changed, 130 insertions(+), 23 deletions(-) (limited to 'dhall_core') diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index bfe769f..24b4401 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -232,7 +232,6 @@ impl Expr { { self.map_ref( |x| rc(map_expr(x.as_ref())), - |_, x| rc(map_expr(x.as_ref())), map_note, map_embed, map_label, @@ -290,7 +289,19 @@ impl Expr { } impl ExprF { - pub fn traverse_ref<'a, SE2, L2, N2, E2, Err, F1, F2, F3, F4, F5>( + pub fn traverse_ref_with_special_handling_of_binders< + 'a, + SE2, + L2, + N2, + E2, + Err, + F1, + F2, + F3, + F4, + F5, + >( &'a self, visit_subexpr: F1, visit_under_binder: F2, @@ -307,7 +318,7 @@ impl ExprF { F4: FnOnce(&'a E) -> Result, F5: FnMut(&'a L) -> Result, { - self.visit(visitor::TraverseRefVisitor { + self.visit(visitor::TraverseRefWithBindersVisitor { visit_subexpr, visit_under_binder, visit_note, @@ -316,12 +327,69 @@ impl ExprF { }) } - pub fn map_ref<'a, SE2, L2, N2, E2, F1, F2, F3, F4, F5>( + pub fn traverse_ref<'a, SE2, L2, N2, E2, Err, F1, F3, F4, F5>( + &'a self, + visit_subexpr: F1, + visit_note: F3, + visit_embed: F4, + visit_label: F5, + ) -> Result, Err> + where + L: Ord, + L2: Ord, + F1: FnMut(&'a SE) -> Result, + F3: FnOnce(&'a N) -> Result, + F4: FnOnce(&'a E) -> Result, + F5: FnMut(&'a L) -> Result, + { + self.visit(visitor::TraverseRefVisitor { + visit_subexpr, + visit_note, + visit_embed, + visit_label, + }) + } + + pub fn map_ref<'a, SE2, L2, N2, E2, F1, F3, F4, F5>( + &'a self, + mut map_subexpr: F1, + map_note: F3, + map_embed: F4, + mut map_label: F5, + ) -> ExprF + where + L: Ord, + L2: Ord, + F1: FnMut(&'a SE) -> SE2, + F3: FnOnce(&'a N) -> N2, + F4: FnOnce(&'a E) -> E2, + F5: FnMut(&'a L) -> L2, + { + trivial_result(self.traverse_ref( + |x| Ok(map_subexpr(x)), + |x| Ok(map_note(x)), + |x| Ok(map_embed(x)), + |x| Ok(map_label(x)), + )) + } + + pub fn map_ref_with_special_handling_of_binders< + 'a, + SE2, + L2, + N2, + E2, + F1, + F2, + F3, + F4, + F5, + >( &'a self, mut map_subexpr: F1, mut map_under_binder: F2, - mut map_note: F3, - mut map_embed: F4, + map_note: F3, + map_embed: F4, mut map_label: F5, ) -> ExprF where @@ -329,11 +397,11 @@ impl ExprF { L2: Ord, F1: FnMut(&'a SE) -> SE2, F2: FnMut(&'a L, &'a SE) -> SE2, - F3: FnMut(&'a N) -> N2, - F4: FnMut(&'a E) -> E2, + F3: FnOnce(&'a N) -> N2, + F4: FnOnce(&'a E) -> E2, F5: FnMut(&'a L) -> L2, { - trivial_result(self.traverse_ref( + trivial_result(self.traverse_ref_with_special_handling_of_binders( |x| Ok(map_subexpr(x)), |l, x| Ok(map_under_binder(l, x)), |x| Ok(map_note(x)), @@ -375,7 +443,11 @@ impl SubExpr { self.0.as_ref() } - fn map_ref<'a, F1, F2>(&'a self, map_expr: F1, map_under_binder: F2) -> Self + pub fn map_subexprs_with_special_handling_of_binders<'a, F1, F2>( + &'a self, + map_expr: F1, + map_under_binder: F2, + ) -> Self where F1: FnMut(&'a Self) -> Self, F2: FnMut(&'a Label, &'a Self) -> Self, @@ -383,9 +455,13 @@ impl SubExpr { match self.as_ref() { ExprF::Embed(_) => SubExpr::clone(self), // Recursive call - ExprF::Note(_, e) => e.map_ref(map_expr, map_under_binder), + ExprF::Note(_, e) => e + .map_subexprs_with_special_handling_of_binders( + map_expr, + map_under_binder, + ), // Call ExprF::map_ref - e => rc(e.map_ref( + e => rc(e.map_ref_with_special_handling_of_binders( map_expr, map_under_binder, |_| unreachable!(), @@ -395,13 +471,6 @@ impl SubExpr { } } - pub fn map_ref_simple(&self, map_expr: F1) -> Self - where - F1: Fn(&Self) -> Self, - { - self.map_ref(&map_expr, |_, e| map_expr(e)) - } - pub fn unroll(&self) -> Expr where N: Clone, @@ -513,7 +582,7 @@ pub fn shift( use crate::ExprF::*; match in_expr.as_ref() { Var(v) => rc(Var(shift_var(delta, var, v))), - _ => in_expr.map_ref( + _ => in_expr.map_subexprs_with_special_handling_of_binders( |e| shift(delta, var, e), |l: &Label, e| { let vl = V(l.clone(), 0); @@ -541,7 +610,7 @@ pub fn subst_shift( match in_expr.as_ref() { Var(v) if v == var => SubExpr::clone(value), Var(v) => rc(Var(shift_var(-1, var, v))), - _ => in_expr.map_ref( + _ => in_expr.map_subexprs_with_special_handling_of_binders( |e| subst_shift(var, &value, e), |l: &Label, e| { let vl = V(l.clone(), 0); diff --git a/dhall_core/src/visitor.rs b/dhall_core/src/visitor.rs index c123275..c6b7321 100644 --- a/dhall_core/src/visitor.rs +++ b/dhall_core/src/visitor.rs @@ -302,7 +302,7 @@ where } } -pub struct TraverseRefVisitor { +pub struct TraverseRefWithBindersVisitor { pub visit_subexpr: F1, pub visit_under_binder: F2, pub visit_note: F3, @@ -312,7 +312,7 @@ pub struct TraverseRefVisitor { impl<'a, SE, L, N, E, SE2, L2, N2, E2, Err, F1, F2, F3, F4, F5> ExprFFallibleVisitor<'a, SE, SE2, L, L2, N, N2, E, E2> - for TraverseRefVisitor + for TraverseRefWithBindersVisitor where SE: 'a, L: 'a, @@ -349,6 +349,44 @@ where } } +pub struct TraverseRefVisitor { + pub visit_subexpr: F1, + pub visit_note: F2, + pub visit_embed: F3, + pub visit_label: F4, +} + +impl<'a, SE, L, N, E, SE2, L2, N2, E2, Err, F1, F2, F3, F4> + ExprFFallibleVisitor<'a, SE, SE2, L, L2, N, N2, E, E2> + for TraverseRefVisitor +where + SE: 'a, + L: 'a, + N: 'a, + E: 'a, + L: Ord, + L2: Ord, + F1: FnMut(&'a SE) -> Result, + F2: FnOnce(&'a N) -> Result, + F3: FnOnce(&'a E) -> Result, + F4: FnMut(&'a L) -> Result, +{ + type Error = Err; + + fn visit_subexpr(&mut self, subexpr: &'a SE) -> Result { + (self.visit_subexpr)(subexpr) + } + fn visit_note(self, note: &'a N) -> Result { + (self.visit_note)(note) + } + fn visit_embed(self, embed: &'a E) -> Result { + (self.visit_embed)(embed) + } + fn visit_label(&mut self, label: &'a L) -> Result { + (self.visit_label)(label) + } +} + pub struct TraverseRefSimpleVisitor { pub visit_subexpr: F1, } -- cgit v1.2.3