From f5d2151d35942b957230c3081a928af3619d9400 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 31 Mar 2019 18:47:34 +0200 Subject: Make SubExpr a newtype --- dhall_core/src/core.rs | 45 +++++++++++++++++++++++++++++++++------------ dhall_core/src/printer.rs | 6 ++++++ dhall_core/src/text.rs | 11 +++++------ 3 files changed, 44 insertions(+), 18 deletions(-) (limited to 'dhall_core/src') 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; pub type ResolvedExpr = SubExpr; pub type DhallExpr = ResolvedExpr; -pub type SubExpr = Rc>; +#[derive(Debug, PartialEq, Eq)] +pub struct SubExpr(pub Rc>); /// Syntax tree for expressions #[derive(Debug, Clone, PartialEq, Eq)] @@ -315,13 +316,33 @@ impl Expr> { } } +impl Clone for SubExpr { + fn clone(&self) -> Self { + SubExpr(Rc::clone(&self.0)) + } +} + +impl std::ops::Deref for SubExpr { + type Target = Rc>; + #[inline(always)] + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +// impl SubExpr { +// pub fn as_ref(&self) -> &Expr { +// self.0.as_ref() +// } +// } + // Remains of a previous life, where everything was in Boxes -pub fn bx(x: T) -> Rc { - Rc::new(x) +pub fn bx(x: Expr) -> SubExpr { + SubExpr(Rc::new(x)) } -pub fn rc(x: T) -> Rc { - Rc::new(x) +pub fn rc(x: Expr) -> SubExpr { + SubExpr(Rc::new(x)) } fn add_ui(u: usize, i: isize) -> usize { @@ -401,7 +422,7 @@ where F2: FnOnce(&Label, &SubExpr) -> SubExpr, { 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( delta: isize, var: &V, - in_expr: &Rc>, -) -> Rc> { + in_expr: &SubExpr, +) -> SubExpr { use crate::Expr::*; let V(x, n) = var; let under_binder = |y: &Label, e: &SubExpr<_, _>| { @@ -529,9 +550,9 @@ pub fn shift( /// pub fn subst( var: &V, - value: &Rc>, - in_expr: &Rc>, -) -> Rc> { + value: &SubExpr, + in_expr: &SubExpr, +) -> SubExpr { use crate::Expr::*; let under_binder = |y: &Label, e: &SubExpr<_, _>| { let V(x, n) = var; @@ -540,7 +561,7 @@ pub fn subst( 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 Display for Expr { } } +impl Display for SubExpr { + 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 { head: String, - tail: Vec<(Rc>, String)>, + tail: Vec<(SubExpr, String)>, } -impl From<(String, Vec<(Rc>, String)>)> +impl From<(String, Vec<(SubExpr, String)>)> for InterpolatedText { - fn from(x: (String, Vec<(Rc>, String)>)) -> Self { + fn from(x: (String, Vec<(SubExpr, String)>)) -> Self { InterpolatedText { head: x.0, tail: x.1, @@ -38,7 +37,7 @@ pub enum InterpolatedTextContents { impl InterpolatedText { pub fn map(&self, mut f: F) -> InterpolatedText where - F: FnMut(&Rc>) -> Rc>, + F: FnMut(&SubExpr) -> SubExpr, { InterpolatedText { head: self.head.clone(), @@ -52,7 +51,7 @@ impl InterpolatedText { 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()))) }), ) -- cgit v1.2.3 From 7374d0524ccd53b256107667b213597c05720d2d Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 31 Mar 2019 19:08:08 +0200 Subject: Move recursion out of Expr --- dhall_core/src/core.rs | 76 +++++++++----------- dhall_core/src/parser.rs | 172 +++++++++++++++++++++++----------------------- dhall_core/src/printer.rs | 8 +-- dhall_core/src/text.rs | 37 +++++----- 4 files changed, 141 insertions(+), 152 deletions(-) (limited to 'dhall_core/src') diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index b49515a..2d11068 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -173,43 +173,39 @@ pub type DhallExpr = ResolvedExpr; #[derive(Debug, PartialEq, Eq)] pub struct SubExpr(pub Rc>); +pub type Expr = ExprF, Note, Embed>; + /// Syntax tree for expressions +// Having the recursion out of the enum definition enables writing +// much more generic code and improves pattern-matching behind +// smart pointers. #[derive(Debug, Clone, PartialEq, Eq)] -pub enum Expr { +pub enum ExprF { /// `Const c ~ c` Const(Const), /// `Var (V x 0) ~ x`
/// `Var (V x n) ~ x@n` Var(V), /// `Lam x A b ~ λ(x : A) -> b` - Lam(Label, SubExpr, SubExpr), + Lam(Label, SubExpr, SubExpr), /// `Pi "_" A B ~ A -> B` /// `Pi x A B ~ ∀(x : A) -> B` - Pi(Label, SubExpr, SubExpr), + Pi(Label, SubExpr, SubExpr), /// `App f A ~ f A` - App(SubExpr, Vec>), + App(SubExpr, Vec), /// `Let x Nothing r e ~ let x = r in e` /// `Let x (Just t) r e ~ let x : t = r in e` - Let( - Label, - Option>, - SubExpr, - SubExpr, - ), + Let(Label, Option, SubExpr, SubExpr), /// `Annot x t ~ x : t` - Annot(SubExpr, SubExpr), + Annot(SubExpr, SubExpr), /// Built-in values Builtin(Builtin), // Binary operations - BinOp(BinOp, SubExpr, SubExpr), + BinOp(BinOp, SubExpr, SubExpr), /// `BoolLit b ~ b` BoolLit(bool), /// `BoolIf x y z ~ if x then y else z` - BoolIf( - SubExpr, - SubExpr, - SubExpr, - ), + BoolIf(SubExpr, SubExpr, SubExpr), /// `NaturalLit n ~ +n` NaturalLit(Natural), /// `IntegerLit n ~ n` @@ -217,39 +213,31 @@ pub enum Expr { /// `DoubleLit n ~ n` DoubleLit(Double), /// `TextLit t ~ t` - TextLit(InterpolatedText), + TextLit(InterpolatedText), /// [] : List t` - EmptyListLit(SubExpr), + EmptyListLit(SubExpr), /// [x, y, z] - NEListLit(Vec>), + NEListLit(Vec), /// None t - EmptyOptionalLit(SubExpr), + EmptyOptionalLit(SubExpr), /// Some e - NEOptionalLit(SubExpr), + NEOptionalLit(SubExpr), /// `Record [(k1, t1), (k2, t2)] ~ { k1 : t1, k2 : t1 }` - RecordType(BTreeMap>), + RecordType(BTreeMap), /// `RecordLit [(k1, v1), (k2, v2)] ~ { k1 = v1, k2 = v2 }` - RecordLit(BTreeMap>), + RecordLit(BTreeMap), /// `Union [(k1, t1), (k2, t2)] ~ < k1 : t1, k2 : t2 >` - UnionType(BTreeMap>), + UnionType(BTreeMap), /// `UnionLit (k1, v1) [(k2, t2), (k3, t3)] ~ < k1 = t1, k2 : t2, k3 : t3 >` - UnionLit( - Label, - SubExpr, - BTreeMap>, - ), + UnionLit(Label, SubExpr, BTreeMap), /// `Merge x y t ~ merge x y : t` - Merge( - SubExpr, - SubExpr, - Option>, - ), + Merge(SubExpr, SubExpr, Option), /// e.x - Field(SubExpr, Label), + Field(SubExpr, Label), /// e.{ x, y, z } - Projection(SubExpr, Vec