diff options
Diffstat (limited to 'dhall_core')
-rw-r--r-- | dhall_core/src/core.rs | 45 | ||||
-rw-r--r-- | dhall_core/src/printer.rs | 6 | ||||
-rw-r--r-- | dhall_core/src/text.rs | 11 |
3 files changed, 44 insertions, 18 deletions
diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index 0ea8c83..b49515a 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -170,7 +170,8 @@ pub type ParsedExpr = SubExpr<X, Import>; pub type ResolvedExpr = SubExpr<X, X>; pub type DhallExpr = ResolvedExpr; -pub type SubExpr<Note, Embed> = Rc<Expr<Note, Embed>>; +#[derive(Debug, PartialEq, Eq)] +pub struct SubExpr<Note, Embed>(pub Rc<Expr<Note, Embed>>); /// Syntax tree for expressions #[derive(Debug, Clone, PartialEq, Eq)] @@ -315,13 +316,33 @@ impl<S: Clone, A: Clone> Expr<S, Expr<S, A>> { } } +impl<N, E> Clone for SubExpr<N, E> { + fn clone(&self) -> Self { + SubExpr(Rc::clone(&self.0)) + } +} + +impl<N, E> std::ops::Deref for SubExpr<N, E> { + type Target = Rc<Expr<N, E>>; + #[inline(always)] + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +// impl<N, E> SubExpr<N, E> { +// pub fn as_ref(&self) -> &Expr<N, E> { +// self.0.as_ref() +// } +// } + // Remains of a previous life, where everything was in Boxes -pub fn bx<T>(x: T) -> Rc<T> { - Rc::new(x) +pub fn bx<N, E>(x: Expr<N, E>) -> SubExpr<N, E> { + SubExpr(Rc::new(x)) } -pub fn rc<T>(x: T) -> Rc<T> { - Rc::new(x) +pub fn rc<N, E>(x: Expr<N, E>) -> SubExpr<N, E> { + SubExpr(Rc::new(x)) } fn add_ui(u: usize, i: isize) -> usize { @@ -401,7 +422,7 @@ where F2: FnOnce(&Label, &SubExpr<S, A>) -> SubExpr<S, A>, { match e.as_ref() { - Expr::Embed(_) => Rc::clone(e), + Expr::Embed(_) => SubExpr::clone(e), Expr::Note(_, e) => { map_subexpr_rc_binder(e, map_expr, map_under_binder) } @@ -500,8 +521,8 @@ where pub fn shift<S, A>( delta: isize, var: &V, - in_expr: &Rc<Expr<S, A>>, -) -> Rc<Expr<S, A>> { + in_expr: &SubExpr<S, A>, +) -> SubExpr<S, A> { use crate::Expr::*; let V(x, n) = var; let under_binder = |y: &Label, e: &SubExpr<_, _>| { @@ -529,9 +550,9 @@ pub fn shift<S, A>( /// pub fn subst<S, A>( var: &V, - value: &Rc<Expr<S, A>>, - in_expr: &Rc<Expr<S, A>>, -) -> Rc<Expr<S, A>> { + value: &SubExpr<S, A>, + in_expr: &SubExpr<S, A>, +) -> SubExpr<S, A> { use crate::Expr::*; let under_binder = |y: &Label, e: &SubExpr<_, _>| { let V(x, n) = var; @@ -540,7 +561,7 @@ pub fn subst<S, A>( subst(newvar, &shift(1, &V(y.clone(), 0), value), e) }; match in_expr.as_ref() { - Var(v) if var == v => Rc::clone(value), + Var(v) if var == v => SubExpr::clone(value), _ => map_subexpr_rc_binder( in_expr, |e| subst(var, value, e), diff --git a/dhall_core/src/printer.rs b/dhall_core/src/printer.rs index 1d1b063..b153d1b 100644 --- a/dhall_core/src/printer.rs +++ b/dhall_core/src/printer.rs @@ -8,6 +8,12 @@ impl<S, A: Display> Display for Expr<S, A> { } } +impl<S, A: Display> Display for SubExpr<S, A> { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + self.as_ref().fmt(f) + } +} + // There is a one-to-one correspondence between the formatter and the grammar. Each phase is // named after a corresponding grammar group, and the structure of the formatter reflects // the relationship between the corresponding grammar rules. This leads to the nice property diff --git a/dhall_core/src/text.rs b/dhall_core/src/text.rs index d377877..eef0797 100644 --- a/dhall_core/src/text.rs +++ b/dhall_core/src/text.rs @@ -1,18 +1,17 @@ use crate::*; use std::iter::FromIterator; use std::ops::Add; -use std::rc::Rc; #[derive(Debug, Clone, PartialEq, Eq)] pub struct InterpolatedText<Note, Embed> { head: String, - tail: Vec<(Rc<Expr<Note, Embed>>, String)>, + tail: Vec<(SubExpr<Note, Embed>, String)>, } -impl<N, E> From<(String, Vec<(Rc<Expr<N, E>>, String)>)> +impl<N, E> From<(String, Vec<(SubExpr<N, E>, String)>)> for InterpolatedText<N, E> { - fn from(x: (String, Vec<(Rc<Expr<N, E>>, String)>)) -> Self { + fn from(x: (String, Vec<(SubExpr<N, E>, String)>)) -> Self { InterpolatedText { head: x.0, tail: x.1, @@ -38,7 +37,7 @@ pub enum InterpolatedTextContents<Note, Embed> { impl<N, E> InterpolatedText<N, E> { pub fn map<N2, E2, F>(&self, mut f: F) -> InterpolatedText<N2, E2> where - F: FnMut(&Rc<Expr<N, E>>) -> Rc<Expr<N2, E2>>, + F: FnMut(&SubExpr<N, E>) -> SubExpr<N2, E2>, { InterpolatedText { head: self.head.clone(), @@ -52,7 +51,7 @@ impl<N, E> InterpolatedText<N, E> { use std::iter::once; once(InterpolatedTextContents::Text(self.head.clone())).chain( self.tail.iter().flat_map(|(e, s)| { - once(InterpolatedTextContents::Expr(Rc::clone(e))) + once(InterpolatedTextContents::Expr(SubExpr::clone(e))) .chain(once(InterpolatedTextContents::Text(s.clone()))) }), ) |