From 250525a05e1af17bb46ceb72879f471e54fb5091 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 2 Sep 2019 23:07:12 +0200 Subject: No need to change the type of Embed when resolving anymore --- dhall_syntax/src/core/expr.rs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'dhall_syntax/src/core/expr.rs') diff --git a/dhall_syntax/src/core/expr.rs b/dhall_syntax/src/core/expr.rs index eeee4d8..f46cafb 100644 --- a/dhall_syntax/src/core/expr.rs +++ b/dhall_syntax/src/core/expr.rs @@ -313,21 +313,25 @@ impl ExprF { } impl RawExpr { - pub fn traverse_resolve( + pub fn traverse_resolve( &self, - visit_import: impl FnMut(&Import>) -> Result, - ) -> Result, Err> { + visit_import: impl FnMut(&Import>) -> Result, + ) -> Result, Err> + where + E: Clone, + { self.traverse_resolve_with_visitor(&mut visitor::ResolveVisitor( visit_import, )) } - pub(crate) fn traverse_resolve_with_visitor( + pub(crate) fn traverse_resolve_with_visitor( &self, visitor: &mut visitor::ResolveVisitor, - ) -> Result, Err> + ) -> Result, Err> where - F1: FnMut(&Import>) -> Result, + E: Clone, + F1: FnMut(&Import>) -> Result, { match self { ExprF::BinOp(BinOp::ImportAlt, l, r) => l @@ -368,10 +372,13 @@ impl Expr { } impl Expr { - pub fn traverse_resolve( + pub fn traverse_resolve( &self, - visit_import: impl FnMut(&Import>) -> Result, - ) -> Result, Err> { + visit_import: impl FnMut(&Import>) -> Result, + ) -> Result, Err> + where + E: Clone, + { Ok(self.rewrap(self.as_ref().traverse_resolve(visit_import)?)) } } -- cgit v1.2.3 From 79595b1ae1a12fa2414d4b6c3c4bb2f7a0a9c094 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 3 Sep 2019 16:24:07 +0200 Subject: Resolve imports by mutating Expr instead of cloning it --- dhall_syntax/src/core/expr.rs | 102 ++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 53 deletions(-) (limited to 'dhall_syntax/src/core/expr.rs') diff --git a/dhall_syntax/src/core/expr.rs b/dhall_syntax/src/core/expr.rs index f46cafb..2cb23c9 100644 --- a/dhall_syntax/src/core/expr.rs +++ b/dhall_syntax/src/core/expr.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use crate::map::{DupTreeMap, DupTreeSet}; -use crate::visitor; +use crate::visitor::{self, ExprFMutVisitor, ExprFVisitor}; use crate::*; pub type Integer = isize; @@ -256,13 +256,6 @@ pub enum ExprF { } impl ExprF { - pub(crate) fn visit<'a, V, Return>(&'a self, v: V) -> Return - where - V: visitor::GenericVisitor<&'a ExprF, Return>, - { - v.visit(self) - } - pub fn traverse_ref_with_special_handling_of_binders<'a, SE2, Err>( &'a self, visit_subexpr: impl FnMut(&'a SE) -> Result, @@ -271,10 +264,11 @@ impl ExprF { where E: Clone, { - self.visit(visitor::TraverseRefWithBindersVisitor { + visitor::TraverseRefWithBindersVisitor { visit_subexpr, visit_under_binder, - }) + } + .visit(self) } fn traverse_ref<'a, SE2, Err>( @@ -284,7 +278,14 @@ impl ExprF { where E: Clone, { - self.visit(visitor::TraverseRefVisitor { visit_subexpr }) + visitor::TraverseRefVisitor { visit_subexpr }.visit(self) + } + + fn traverse_mut<'a, Err>( + &'a mut self, + visit_subexpr: impl FnMut(&'a mut SE) -> Result<(), Err>, + ) -> Result<(), Err> { + visitor::TraverseMutVisitor { visit_subexpr }.visit(self) } pub fn map_ref_with_special_handling_of_binders<'a, SE2>( @@ -310,42 +311,9 @@ impl ExprF { { trivial_result(self.traverse_ref(|x| Ok(map_subexpr(x)))) } -} - -impl RawExpr { - pub fn traverse_resolve( - &self, - visit_import: impl FnMut(&Import>) -> Result, - ) -> Result, Err> - where - E: Clone, - { - self.traverse_resolve_with_visitor(&mut visitor::ResolveVisitor( - visit_import, - )) - } - pub(crate) fn traverse_resolve_with_visitor( - &self, - visitor: &mut visitor::ResolveVisitor, - ) -> Result, Err> - where - E: Clone, - F1: FnMut(&Import>) -> Result, - { - match self { - ExprF::BinOp(BinOp::ImportAlt, l, r) => l - .as_ref() - .traverse_resolve_with_visitor(visitor) - .or_else(|_| r.as_ref().traverse_resolve_with_visitor(visitor)), - _ => { - let e = self.visit(&mut *visitor)?; - Ok(match &e { - ExprF::Import(import) => ExprF::Embed((visitor.0)(import)?), - _ => e, - }) - } - } + pub fn map_mut<'a>(&'a mut self, mut map_subexpr: impl FnMut(&'a mut SE)) { + trivial_result(self.traverse_mut(|x| Ok(map_subexpr(x)))) } } @@ -353,6 +321,9 @@ impl Expr { pub fn as_ref(&self) -> &RawExpr { &self.0.as_ref().0 } + pub fn as_mut(&mut self) -> &mut RawExpr { + &mut self.0.as_mut().0 + } pub fn new(x: RawExpr, n: Span) -> Self { Expr(Box::new((x, Some(n)))) @@ -369,17 +340,42 @@ impl Expr { pub fn rewrap(&self, x: RawExpr) -> Expr { Expr(Box::new((x, (self.0).1.clone()))) } -} -impl Expr { - pub fn traverse_resolve( - &self, - visit_import: impl FnMut(&Import>) -> Result, - ) -> Result, Err> + pub fn traverse_resolve_mut( + &mut self, + f: &mut F1, + ) -> Result<(), Err> where E: Clone, + F1: FnMut(Import>) -> Result, { - Ok(self.rewrap(self.as_ref().traverse_resolve(visit_import)?)) + match self.as_mut() { + ExprF::BinOp(BinOp::ImportAlt, l, r) => { + let garbage_expr = ExprF::BoolLit(false); + let new_self = if l.traverse_resolve_mut(f).is_ok() { + l + } else { + r.traverse_resolve_mut(f)?; + r + }; + *self.as_mut() = + std::mem::replace(new_self.as_mut(), garbage_expr); + } + _ => { + self.as_mut().traverse_mut(|e| e.traverse_resolve_mut(f))?; + if let ExprF::Import(import) = self.as_mut() { + let garbage_import = Import { + mode: ImportMode::Code, + location: ImportLocation::Missing, + hash: None, + }; + // Move out of &mut import + let import = std::mem::replace(import, garbage_import); + *self.as_mut() = ExprF::Embed(f(import)?); + } + } + } + Ok(()) } } -- cgit v1.2.3