summaryrefslogtreecommitdiff
path: root/dhall_syntax/src
diff options
context:
space:
mode:
Diffstat (limited to 'dhall_syntax/src')
-rw-r--r--dhall_syntax/src/core.rs207
-rw-r--r--dhall_syntax/src/parser.rs24
-rw-r--r--dhall_syntax/src/printer.rs44
-rw-r--r--dhall_syntax/src/visitor.rs130
4 files changed, 187 insertions, 218 deletions
diff --git a/dhall_syntax/src/core.rs b/dhall_syntax/src/core.rs
index c8a2425..a186d19 100644
--- a/dhall_syntax/src/core.rs
+++ b/dhall_syntax/src/core.rs
@@ -60,7 +60,19 @@ pub enum Const {
/// The `Int` field is a DeBruijn index.
/// See dhall-lang/standard/semantics.md for details
#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct Var<Label>(pub Label, pub usize);
+pub struct V<Label>(pub Label, pub usize);
+
+// This is only for the specific `Label` type, not generic
+impl From<Label> for V<Label> {
+ fn from(x: Label) -> V<Label> {
+ V(x, 0)
+ }
+}
+impl<'a> From<&'a Label> for V<Label> {
+ fn from(x: &'a Label) -> V<Label> {
+ V(x.clone(), 0)
+ }
+}
// Definition order must match precedence order for
// pretty-printing to work correctly
@@ -125,52 +137,44 @@ pub enum Builtin {
TextShow,
}
-pub type ParsedExpr = SubExpr<Label, X, Import>;
-pub type ResolvedExpr = SubExpr<Label, X, X>;
+pub type ParsedExpr = SubExpr<X, Import>;
+pub type ResolvedExpr = SubExpr<X, X>;
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<VarLabel, Note, Embed>(
- Rc<(Expr<VarLabel, Note, Embed>, Option<Note>)>,
-);
+pub struct SubExpr<Note, Embed>(Rc<(Expr<Note, Embed>, Option<Note>)>);
-impl<VarLabel: PartialEq, Note, Embed: PartialEq> std::cmp::PartialEq
- for SubExpr<VarLabel, Note, Embed>
-{
+impl<Note, Embed: PartialEq> std::cmp::PartialEq for SubExpr<Note, Embed> {
fn eq(&self, other: &Self) -> bool {
self.0.as_ref().0 == other.0.as_ref().0
}
}
-impl<VarLabel: Eq, Note, Embed: Eq> std::cmp::Eq
- for SubExpr<VarLabel, Note, Embed>
-{
-}
+impl<Note, Embed: Eq> std::cmp::Eq for SubExpr<Note, Embed> {}
-pub type Expr<VarLabel, Note, Embed> =
- ExprF<SubExpr<VarLabel, Note, Embed>, VarLabel, Embed>;
+pub type Expr<Note, Embed> = ExprF<SubExpr<Note, Embed>, Label, 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 ExprF<SubExpr, VarLabel, Embed> {
+pub enum ExprF<SubExpr, Label, Embed> {
Const(Const),
/// `x`
/// `x@n`
- Var(Var<VarLabel>),
+ Var(V<Label>),
/// `λ(x : A) -> b`
- Lam(VarLabel, SubExpr, SubExpr),
+ Lam(Label, SubExpr, SubExpr),
/// `A -> B`
/// `∀(x : A) -> B`
- Pi(VarLabel, SubExpr, SubExpr),
+ Pi(Label, SubExpr, SubExpr),
/// `f a`
App(SubExpr, SubExpr),
/// `let x = r in e`
/// `let x : t = r in e`
- Let(VarLabel, Option<SubExpr>, SubExpr, SubExpr),
+ Let(Label, Option<SubExpr>, SubExpr, SubExpr),
/// `x : t`
Annot(SubExpr, SubExpr),
/// Built-in values
@@ -231,7 +235,11 @@ impl<SE, L, E> ExprF<SE, L, E> {
visit_under_binder: impl FnOnce(&'a L, &'a SE) -> Result<SE2, Err>,
visit_embed: impl FnOnce(&'a E) -> Result<E2, Err>,
visit_label: impl FnMut(&'a L) -> Result<L2, Err>,
- ) -> Result<ExprF<SE2, L2, E2>, Err> {
+ ) -> Result<ExprF<SE2, L2, E2>, Err>
+ where
+ L: Ord,
+ L2: Ord,
+ {
self.visit(visitor::TraverseRefWithBindersVisitor {
visit_subexpr,
visit_under_binder,
@@ -245,7 +253,11 @@ impl<SE, L, E> ExprF<SE, L, E> {
visit_subexpr: impl FnMut(&'a SE) -> Result<SE2, Err>,
visit_embed: impl FnOnce(&'a E) -> Result<E2, Err>,
visit_label: impl FnMut(&'a L) -> Result<L2, Err>,
- ) -> Result<ExprF<SE2, L2, E2>, Err> {
+ ) -> Result<ExprF<SE2, L2, E2>, Err>
+ where
+ L: Ord,
+ L2: Ord,
+ {
self.visit(visitor::TraverseRefVisitor {
visit_subexpr,
visit_embed,
@@ -259,7 +271,11 @@ impl<SE, L, E> ExprF<SE, L, E> {
mut map_under_binder: impl FnMut(&'a L, &'a SE) -> SE2,
map_embed: impl FnOnce(&'a E) -> E2,
mut map_label: impl FnMut(&'a L) -> L2,
- ) -> ExprF<SE2, L2, E2> {
+ ) -> ExprF<SE2, L2, E2>
+ where
+ L: Ord,
+ L2: Ord,
+ {
trivial_result(self.traverse_ref_with_special_handling_of_binders(
|x| Ok(map_subexpr(x)),
|l, x| Ok(map_under_binder(l, x)),
@@ -273,7 +289,11 @@ impl<SE, L, E> ExprF<SE, L, E> {
mut map_subexpr: impl FnMut(&'a SE) -> SE2,
map_embed: impl FnOnce(&'a E) -> E2,
mut map_label: impl FnMut(&'a L) -> L2,
- ) -> ExprF<SE2, L2, E2> {
+ ) -> ExprF<SE2, L2, E2>
+ where
+ L: Ord,
+ L2: Ord,
+ {
trivial_result(self.traverse_ref(
|x| Ok(map_subexpr(x)),
|x| Ok(map_embed(x)),
@@ -286,7 +306,7 @@ impl<SE, L, E> ExprF<SE, L, E> {
visit_subexpr: impl FnMut(&'a SE) -> Result<SE2, Err>,
) -> Result<ExprF<SE2, L, E>, Err>
where
- L: Clone,
+ L: Ord + Clone,
E: Clone,
{
self.traverse_ref(
@@ -301,31 +321,26 @@ impl<SE, L, E> ExprF<SE, L, E> {
map_subexpr: impl Fn(&'a SE) -> SE2,
) -> ExprF<SE2, L, E>
where
- L: Clone,
+ L: Ord + Clone,
E: Clone,
{
self.map_ref(map_subexpr, E::clone, L::clone)
}
}
-impl<L, N, E> Expr<L, N, E> {
+impl<N, E> Expr<N, E> {
fn traverse_embed<E2, Err>(
&self,
visit_embed: impl FnMut(&E) -> Result<E2, Err>,
- ) -> Result<Expr<L, N, E2>, Err>
+ ) -> Result<Expr<N, E2>, Err>
where
- L: Clone,
N: Clone,
{
self.visit(&mut visitor::TraverseEmbedVisitor(visit_embed))
}
- fn map_embed<E2>(
- &self,
- mut map_embed: impl FnMut(&E) -> E2,
- ) -> Expr<L, N, E2>
+ fn map_embed<E2>(&self, mut map_embed: impl FnMut(&E) -> E2) -> Expr<N, E2>
where
- L: Clone,
N: Clone,
{
trivial_result(self.traverse_embed(|x| Ok(map_embed(x))))
@@ -333,52 +348,52 @@ impl<L, N, E> Expr<L, N, E> {
pub fn squash_embed<E2>(
&self,
- f: impl FnMut(&E) -> SubExpr<L, N, E2>,
- ) -> SubExpr<L, N, E2>
+ f: impl FnMut(&E) -> SubExpr<N, E2>,
+ ) -> SubExpr<N, E2>
where
- L: Clone,
N: Clone,
{
trivial_result(self.visit(&mut visitor::SquashEmbedVisitor(f)))
}
}
-impl<L: Clone, E: Clone> Expr<L, X, E> {
- pub fn note_absurd<N>(&self) -> Expr<L, N, E> {
+impl<E: Clone> Expr<X, E> {
+ pub fn note_absurd<N>(&self) -> Expr<N, E> {
self.visit(&mut visitor::NoteAbsurdVisitor)
}
}
-impl<L: Clone, N: Clone> Expr<L, N, X> {
- pub fn embed_absurd<E>(&self) -> Expr<L, N, E> {
+impl<N: Clone> Expr<N, X> {
+ pub fn embed_absurd<E>(&self) -> Expr<N, E> {
self.visit(&mut visitor::EmbedAbsurdVisitor)
}
}
-impl<V, N, E> SubExpr<V, N, E> {
- pub fn as_ref(&self) -> &Expr<V, N, E> {
+impl<N, E> SubExpr<N, E> {
+ pub fn as_ref(&self) -> &Expr<N, E> {
&self.0.as_ref().0
}
- pub fn new(x: Expr<V, N, E>, n: N) -> Self {
+ pub fn new(x: Expr<N, E>, n: N) -> Self {
SubExpr(Rc::new((x, Some(n))))
}
- pub fn from_expr_no_note(x: Expr<V, N, E>) -> Self {
+ pub fn from_expr_no_note(x: Expr<N, E>) -> Self {
SubExpr(Rc::new((x, None)))
}
- pub fn unnote(&self) -> SubExpr<V, X, E>
+ pub fn unnote(&self) -> SubExpr<X, E>
where
- V: Clone,
E: Clone,
{
SubExpr::from_expr_no_note(
self.as_ref().visit(&mut visitor::UnNoteVisitor),
)
}
+}
- pub fn rewrap<E2>(&self, x: Expr<V, N, E2>) -> SubExpr<V, N, E2>
+impl<N: Clone, E> SubExpr<N, E> {
+ pub fn rewrap<E2>(&self, x: Expr<N, E2>) -> SubExpr<N, E2>
where
N: Clone,
{
@@ -388,9 +403,8 @@ impl<V, N, E> SubExpr<V, N, E> {
pub fn traverse_embed<E2, Err>(
&self,
visit_embed: impl FnMut(&E) -> Result<E2, Err>,
- ) -> Result<SubExpr<V, N, E2>, Err>
+ ) -> Result<SubExpr<N, E2>, Err>
where
- V: Clone,
N: Clone,
{
Ok(self.rewrap(self.as_ref().traverse_embed(visit_embed)?))
@@ -399,9 +413,8 @@ impl<V, N, E> SubExpr<V, N, E> {
pub fn map_embed<E2>(
&self,
map_embed: impl FnMut(&E) -> E2,
- ) -> SubExpr<V, N, E2>
+ ) -> SubExpr<N, E2>
where
- V: Clone,
N: Clone,
{
self.rewrap(self.as_ref().map_embed(map_embed))
@@ -410,12 +423,8 @@ impl<V, N, E> SubExpr<V, N, E> {
pub fn map_subexprs_with_special_handling_of_binders<'a>(
&'a self,
map_expr: impl FnMut(&'a Self) -> Self,
- map_under_binder: impl FnMut(&'a V, &'a Self) -> Self,
- ) -> Self
- where
- V: Clone,
- N: Clone,
- {
+ map_under_binder: impl FnMut(&'a Label, &'a Self) -> Self,
+ ) -> Self {
match self.as_ref() {
ExprF::Embed(_) => SubExpr::clone(self),
// This calls ExprF::map_ref
@@ -423,7 +432,7 @@ impl<V, N, E> SubExpr<V, N, E> {
map_expr,
map_under_binder,
|_| unreachable!(),
- V::clone,
+ Label::clone,
)),
}
}
@@ -432,34 +441,26 @@ impl<V, N, E> SubExpr<V, N, E> {
/// capture by shifting variable indices
/// See https://github.com/dhall-lang/dhall-lang/blob/master/standard/semantics.md#shift
/// for details
- pub fn shift(&self, delta: isize, var: &Var<V>) -> Self
- where
- V: Clone + PartialEq,
- N: Clone,
- {
+ pub fn shift(&self, delta: isize, var: &V<Label>) -> Self {
match self.as_ref() {
ExprF::Var(v) => self.rewrap(ExprF::Var(v.shift(delta, var))),
_ => self.map_subexprs_with_special_handling_of_binders(
|e| e.shift(delta, var),
- |x: &V, e| e.shift(delta, &var.shift(1, &Var::new(x.clone()))),
+ |x: &Label, e| e.shift(delta, &var.shift(1, &x.into())),
),
}
}
- pub fn subst_shift(&self, var: &Var<V>, val: &Self) -> Self
- where
- V: Clone + PartialEq,
- N: Clone,
- {
+ pub fn subst_shift(&self, var: &V<Label>, val: &Self) -> Self {
match self.as_ref() {
ExprF::Var(v) if v == var => val.clone(),
ExprF::Var(v) => self.rewrap(ExprF::Var(v.shift(-1, var))),
_ => self.map_subexprs_with_special_handling_of_binders(
|e| e.subst_shift(var, val),
- |x: &V, e| {
+ |x: &Label, e| {
e.subst_shift(
- &var.shift(1, &Var::new(x.clone())),
- &val.shift(1, &Var::new(x.clone())),
+ &var.shift(1, &x.into()),
+ &val.shift(1, &x.into()),
)
},
),
@@ -467,26 +468,26 @@ impl<V, N, E> SubExpr<V, N, E> {
}
}
-impl<L: Clone, N: Clone> SubExpr<L, N, X> {
- pub fn embed_absurd<T>(&self) -> SubExpr<L, N, T> {
+impl<N: Clone> SubExpr<N, X> {
+ pub fn embed_absurd<T>(&self) -> SubExpr<N, T> {
self.rewrap(self.as_ref().embed_absurd())
}
}
-impl<L: Clone, E: Clone> SubExpr<L, X, E> {
- pub fn note_absurd<N>(&self) -> SubExpr<L, N, E> {
+impl<E: Clone> SubExpr<X, E> {
+ pub fn note_absurd<N>(&self) -> SubExpr<N, E> {
SubExpr::from_expr_no_note(self.as_ref().note_absurd())
}
}
-impl<L, N, E> Clone for SubExpr<L, N, E> {
+impl<N, E> Clone for SubExpr<N, E> {
fn clone(&self) -> Self {
SubExpr(Rc::clone(&self.0))
}
}
// Should probably rename this
-pub fn rc<L, E>(x: Expr<L, X, E>) -> SubExpr<L, X, E> {
+pub fn rc<E>(x: Expr<X, E>) -> SubExpr<X, E> {
SubExpr::from_expr_no_note(x)
}
@@ -500,35 +501,18 @@ fn add_ui(u: usize, i: isize) -> usize {
}
}
-impl<L> Var<L> {
- fn new(x: L) -> Self {
- Var(x, 0)
- }
-}
-impl<L: PartialEq + Clone> Var<L> {
- pub fn shift(&self, delta: isize, var: &Var<L>) -> Self {
- let Var(x, n) = var;
- let Var(y, m) = self;
+impl<Label: PartialEq + Clone> V<Label> {
+ pub fn shift(&self, delta: isize, var: &V<Label>) -> Self {
+ let V(x, n) = var;
+ let V(y, m) = self;
if x == y && n <= m {
- Var(y.clone(), add_ui(*m, delta))
+ V(y.clone(), add_ui(*m, delta))
} else {
- Var(y.clone(), *m)
+ V(y.clone(), *m)
}
}
}
-// This is only for the specific `Label` type, not generic
-impl From<Label> for Var<Label> {
- fn from(x: Label) -> Var<Label> {
- Var(x, 0)
- }
-}
-impl<'a> From<&'a Label> for Var<Label> {
- fn from(x: &'a Label) -> Var<Label> {
- Var(x.clone(), 0)
- }
-}
-
/// `shift` is used by both normalization and type-checking to avoid variable
/// capture by shifting variable indices
/// See https://github.com/dhall-lang/dhall-lang/blob/master/standard/semantics.md#shift
@@ -536,9 +520,9 @@ impl<'a> From<&'a Label> for Var<Label> {
///
pub fn shift<N, E>(
delta: isize,
- var: &Var<Label>,
- in_expr: &SubExpr<Label, N, E>,
-) -> SubExpr<Label, N, E>
+ var: &V<Label>,
+ in_expr: &SubExpr<N, E>,
+) -> SubExpr<N, E>
where
N: Clone,
{
@@ -547,8 +531,8 @@ where
pub fn shift0_multiple<N, E>(
deltas: &HashMap<Label, isize>,
- in_expr: &SubExpr<Label, N, E>,
-) -> SubExpr<Label, N, E>
+ in_expr: &SubExpr<N, E>,
+) -> SubExpr<N, E>
where
N: Clone,
{
@@ -558,15 +542,16 @@ where
fn shift0_multiple_inner<N, E>(
ctx: &Context<Label, ()>,
deltas: &HashMap<Label, isize>,
- in_expr: &SubExpr<Label, N, E>,
-) -> SubExpr<Label, N, E>
+ in_expr: &SubExpr<N, E>,
+) -> SubExpr<N, E>
where
N: Clone,
{
+ use crate::ExprF::*;
match in_expr.as_ref() {
- ExprF::Var(Var(y, m)) if ctx.lookup(y, *m).is_none() => {
+ Var(V(y, m)) if ctx.lookup(y, *m).is_none() => {
let delta = deltas.get(y).unwrap_or(&0);
- in_expr.rewrap(ExprF::Var(Var(y.clone(), add_ui(*m, *delta))))
+ in_expr.rewrap(Var(V(y.clone(), add_ui(*m, *delta))))
}
_ => in_expr.map_subexprs_with_special_handling_of_binders(
|e| shift0_multiple_inner(ctx, deltas, e),
diff --git a/dhall_syntax/src/parser.rs b/dhall_syntax/src/parser.rs
index bdef553..83ccc1e 100644
--- a/dhall_syntax/src/parser.rs
+++ b/dhall_syntax/src/parser.rs
@@ -8,13 +8,7 @@ use std::rc::Rc;
use dhall_generated_parser::{DhallParser, Rule};
-use crate::ExprF::{
- Annot, App, BinOp, BoolIf, BoolLit, Builtin, Const, DoubleLit, Embed,
- EmptyListLit, Field, IntegerLit, Lam, Let, Merge, NEListLit, NaturalLit,
- OldOptionalLit, Pi, Projection, RecordLit, RecordType, SomeLit, TextLit,
- UnionLit, UnionType,
-};
-
+use crate::ExprF::*;
use crate::*;
// This file consumes the parse tree generated by pest and turns it into
@@ -22,10 +16,10 @@ 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<Label, Span, Import>;
-type ParsedSubExpr = SubExpr<Label, Span, Import>;
-type ParsedText = InterpolatedText<ParsedSubExpr>;
-type ParsedTextContents = InterpolatedTextContents<ParsedSubExpr>;
+type ParsedExpr = Expr<Span, Import>;
+type ParsedSubExpr = SubExpr<Span, Import>;
+type ParsedText = InterpolatedText<SubExpr<Span, Import>>;
+type ParsedTextContents = InterpolatedTextContents<SubExpr<Span, Import>>;
pub type ParseError = pest::error::Error<Rule>;
@@ -510,17 +504,17 @@ make_parser! {
rule!(identifier<ParsedSubExpr> as expression; span; children!(
[variable(v)] => {
- spanned(span, ExprF::Var(v))
+ spanned(span, Var(v))
},
[builtin(e)] => e,
));
- rule!(variable<Var<Label>>; children!(
+ rule!(variable<V<Label>>; children!(
[label(l), natural_literal(idx)] => {
- Var(l, idx)
+ V(l, idx)
},
[label(l)] => {
- Var(l, 0)
+ V(l, 0)
},
));
diff --git a/dhall_syntax/src/printer.rs b/dhall_syntax/src/printer.rs
index 9cc1b46..e3b180b 100644
--- a/dhall_syntax/src/printer.rs
+++ b/dhall_syntax/src/printer.rs
@@ -3,9 +3,7 @@ use itertools::Itertools;
use std::fmt::{self, Display};
/// Generic instance that delegates to subexpressions
-impl<SE: Display + Clone, L: Display + Clone, E: Display> Display
- for ExprF<SE, L, E>
-{
+impl<SE: Display + Clone, E: Display> Display for ExprF<SE, Label, E> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
use crate::ExprF::*;
match self {
@@ -15,10 +13,9 @@ impl<SE: Display + Clone, L: Display + Clone, E: Display> Display
BoolIf(a, b, c) => {
write!(f, "if {} then {} else {}", a, b, c)?;
}
- // TODO: arrow type
- // Pi(a, b, c) if &String::from(a) == "_" => {
- // write!(f, "{} → {}", b, c)?;
- // }
+ Pi(a, b, c) if &String::from(a) == "_" => {
+ write!(f, "{} → {}", b, c)?;
+ }
Pi(a, b, c) => {
write!(f, "∀({} : {}) → {}", a, b, c)?;
}
@@ -127,25 +124,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, L, S, A>(&'a SubExpr<L, S, A>, PrintPhase);
+struct PhasedExpr<'a, S, A>(&'a SubExpr<S, A>, PrintPhase);
-impl<'a, L: Display + Clone, S: Clone, A: Display + Clone> Display
- for PhasedExpr<'a, L, S, A>
-{
+impl<'a, S: Clone, A: Display + Clone> Display for PhasedExpr<'a, S, A> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.0.as_ref().fmt_phase(f, self.1)
}
}
-impl<'a, L: Display + Clone, S: Clone, A: Display + Clone>
- PhasedExpr<'a, L, S, A>
-{
- fn phase(self, phase: PrintPhase) -> PhasedExpr<'a, L, S, A> {
+impl<'a, S: Clone, A: Display + Clone> PhasedExpr<'a, S, A> {
+ fn phase(self, phase: PrintPhase) -> PhasedExpr<'a, S, A> {
PhasedExpr(self.0, phase)
}
}
-impl<L: Display + Clone, S: Clone, A: Display + Clone> Expr<L, S, A> {
+impl<S: Clone, A: Display + Clone> Expr<S, A> {
fn fmt_phase(
&self,
f: &mut fmt::Formatter,
@@ -179,12 +172,11 @@ impl<L: Display + Clone, S: Clone, A: Display + Clone> Expr<L, S, A> {
// Annotate subexpressions with the appropriate phase, defaulting to Base
let phased_self = match self.map_ref_simple(|e| PhasedExpr(e, Base)) {
Pi(a, b, c) => {
- // TODO: arrow type
- // if &String::from(&a) == "_" {
- // Pi(a, b.phase(Operator), c)
- // } else {
- Pi(a, b, c)
- // }
+ if &String::from(&a) == "_" {
+ Pi(a, b.phase(Operator), c)
+ } else {
+ Pi(a, b, c)
+ }
}
Merge(a, b, c) => Merge(
a.phase(Import),
@@ -220,9 +212,7 @@ impl<L: Display + Clone, S: Clone, A: Display + Clone> Expr<L, S, A> {
}
}
-impl<L: Display + Clone, S: Clone, A: Display + Clone> Display
- for SubExpr<L, S, A>
-{
+impl<S: Clone, A: Display + Clone> Display for SubExpr<S, A> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.as_ref().fmt_phase(f, PrintPhase::Base)
}
@@ -484,9 +474,9 @@ impl Display for Scheme {
}
}
-impl<Label: Display> Display for Var<Label> {
+impl<Label: Display> Display for V<Label> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- let Var(x, n) = self;
+ let V(x, n) = self;
x.fmt(f)?;
if *n != 0 {
write!(f, "@{}", n)?;
diff --git a/dhall_syntax/src/visitor.rs b/dhall_syntax/src/visitor.rs
index a8e5a8c..7fdf217 100644
--- a/dhall_syntax/src/visitor.rs
+++ b/dhall_syntax/src/visitor.rs
@@ -48,6 +48,8 @@ pub trait ExprFVeryGenericVisitor<'a, Ret, SE1, L1, E1>: Sized {
impl<'a, T, Ret, SE1, L1, E1>
GenericVisitor<&'a ExprF<SE1, L1, E1>, Result<Ret, T::Error>> for T
where
+ L1: Ord,
+ T::L2: Ord,
T: ExprFVeryGenericVisitor<'a, Ret, SE1, L1, E1>,
{
fn visit(self, input: &'a ExprF<SE1, L1, E1>) -> Result<Ret, T::Error> {
@@ -67,27 +69,31 @@ where
})
}
fn btmap<'a, V, Ret, SE, L, E>(
- x: &'a BTreeMap<Label, SE>,
+ x: &'a BTreeMap<L, SE>,
mut v: V,
- ) -> Result<BTreeMap<Label, V::SE2>, V::Error>
+ ) -> Result<BTreeMap<V::L2, V::SE2>, V::Error>
where
+ L: Ord,
+ V::L2: Ord,
V: ExprFVeryGenericVisitor<'a, Ret, SE, L, E>,
{
x.iter()
- .map(|(k, x)| Ok((k.clone(), v.visit_subexpr(x)?)))
+ .map(|(k, x)| Ok((v.visit_label(k)?, v.visit_subexpr(x)?)))
.collect()
}
fn btoptmap<'a, V, Ret, SE, L, E>(
- x: &'a BTreeMap<Label, Option<SE>>,
+ x: &'a BTreeMap<L, Option<SE>>,
mut v: V,
- ) -> Result<BTreeMap<Label, Option<V::SE2>>, V::Error>
+ ) -> Result<BTreeMap<V::L2, Option<V::SE2>>, V::Error>
where
+ L: Ord,
+ V::L2: Ord,
V: ExprFVeryGenericVisitor<'a, Ret, SE, L, E>,
{
x.iter()
.map(|(k, x)| {
Ok((
- k.clone(),
+ v.visit_label(k)?,
match x {
Some(x) => Some(v.visit_subexpr(x)?),
None => None,
@@ -98,14 +104,9 @@ where
}
let mut v = self;
- use crate::ExprF::{
- Annot, App, BinOp, BoolIf, BoolLit, Builtin, Const, DoubleLit,
- Embed, EmptyListLit, Field, IntegerLit, Lam, Let, Merge, NEListLit,
- NaturalLit, OldOptionalLit, Pi, Projection, RecordLit, RecordType,
- SomeLit, TextLit, UnionLit, UnionType,
- };
+ use crate::ExprF::*;
T::visit_resulting_exprf(match input {
- ExprF::Var(Var(l, n)) => ExprF::Var(Var(v.visit_label(l)?, *n)),
+ Var(V(l, n)) => Var(V(v.visit_label(l)?, *n)),
Lam(l, t, e) => {
let t = v.visit_subexpr(t)?;
let (l, e) = v.visit_binder(l, e)?;
@@ -149,16 +150,20 @@ where
RecordType(kts) => RecordType(btmap(kts, v)?),
RecordLit(kvs) => RecordLit(btmap(kvs, v)?),
UnionType(kts) => UnionType(btoptmap(kts, v)?),
- UnionLit(l, x, kts) => {
- UnionLit(l.clone(), v.visit_subexpr(x)?, btoptmap(kts, v)?)
- }
+ UnionLit(k, x, kts) => UnionLit(
+ v.visit_label(k)?,
+ v.visit_subexpr(x)?,
+ btoptmap(kts, v)?,
+ ),
Merge(x, y, t) => Merge(
v.visit_subexpr(x)?,
v.visit_subexpr(y)?,
opt(t, |e| v.visit_subexpr(e))?,
),
- Field(e, l) => Field(v.visit_subexpr(e)?, l.clone()),
- Projection(e, ls) => Projection(v.visit_subexpr(e)?, ls.clone()),
+ Field(e, l) => Field(v.visit_subexpr(e)?, v.visit_label(l)?),
+ Projection(e, ls) => {
+ Projection(v.visit_subexpr(e)?, vec(ls, |l| v.visit_label(l))?)
+ }
Embed(a) => return v.visit_embed_squash(a),
})
}
@@ -309,6 +314,8 @@ where
impl<'a, T, SE1, SE2, L1, L2, E1, E2>
GenericVisitor<&'a ExprF<SE1, L1, E1>, ExprF<SE2, L2, E2>> for T
where
+ L1: Ord,
+ L2: Ord,
T: ExprFInFallibleVisitor<'a, SE1, SE2, L1, L2, E1, E2>,
{
fn visit(self, input: &'a ExprF<SE1, L1, E1>) -> ExprF<SE2, L2, E2> {
@@ -330,6 +337,8 @@ where
SE: 'a,
L: 'a,
E: 'a,
+ L: Ord,
+ L2: Ord,
F1: FnMut(&'a SE) -> Result<SE2, Err>,
F2: FnOnce(&'a L, &'a SE) -> Result<SE2, Err>,
F4: FnOnce(&'a E) -> Result<E2, Err>,
@@ -368,6 +377,8 @@ where
SE: 'a,
L: 'a,
E: 'a,
+ L: Ord,
+ L2: Ord,
F1: FnMut(&'a SE) -> Result<SE2, Err>,
F3: FnOnce(&'a E) -> Result<E2, Err>,
F4: FnMut(&'a L) -> Result<L2, Err>,
@@ -387,11 +398,10 @@ where
pub struct TraverseEmbedVisitor<F1>(pub F1);
-impl<'a, 'b, L, N, E, E2, Err, F1>
- ExprFFallibleVisitor<'a, SubExpr<L, N, E>, SubExpr<L, N, E2>, L, L, E, E2>
+impl<'a, 'b, N, E, E2, Err, F1>
+ ExprFFallibleVisitor<'a, SubExpr<N, E>, SubExpr<N, E2>, Label, Label, E, E2>
for &'b mut TraverseEmbedVisitor<F1>
where
- L: Clone + 'a,
N: Clone + 'a,
F1: FnMut(&E) -> Result<E2, Err>,
{
@@ -399,48 +409,50 @@ where
fn visit_subexpr(
&mut self,
- subexpr: &'a SubExpr<L, N, E>,
- ) -> Result<SubExpr<L, N, E2>, Self::Error> {
+ subexpr: &'a SubExpr<N, E>,
+ ) -> Result<SubExpr<N, E2>, Self::Error> {
Ok(subexpr.rewrap(subexpr.as_ref().visit(&mut **self)?))
}
fn visit_embed(self, embed: &'a E) -> Result<E2, Self::Error> {
(self.0)(embed)
}
- fn visit_label(&mut self, label: &'a L) -> Result<L, Self::Error> {
- Ok(L::clone(label))
+ fn visit_label(&mut self, label: &'a Label) -> Result<Label, Self::Error> {
+ Ok(Label::clone(label))
}
}
pub struct SquashEmbedVisitor<F1>(pub F1);
-impl<'a, 'b, L, N, E1, E2, F1>
- ExprFVeryGenericVisitor<'a, SubExpr<L, N, E2>, SubExpr<L, N, E1>, L, E1>
+impl<'a, 'b, N, E1, E2, F1>
+ ExprFVeryGenericVisitor<'a, SubExpr<N, E2>, SubExpr<N, E1>, Label, E1>
for &'b mut SquashEmbedVisitor<F1>
where
- L: Clone + 'a,
N: Clone + 'a,
- F1: FnMut(&E1) -> SubExpr<L, N, E2>,
+ F1: FnMut(&E1) -> SubExpr<N, E2>,
{
type Error = X;
- type SE2 = SubExpr<L, N, E2>;
- type L2 = L;
+ type SE2 = SubExpr<N, E2>;
+ type L2 = Label;
type E2 = E2;
fn visit_subexpr(
&mut self,
- subexpr: &'a SubExpr<L, N, E1>,
+ subexpr: &'a SubExpr<N, E1>,
) -> Result<Self::SE2, Self::Error> {
Ok(subexpr.as_ref().visit(&mut **self)?)
}
- fn visit_label(&mut self, label: &'a L) -> Result<Self::L2, Self::Error> {
- Ok(L::clone(label))
+ fn visit_label(
+ &mut self,
+ label: &'a Label,
+ ) -> Result<Self::L2, Self::Error> {
+ Ok(Label::clone(label))
}
fn visit_binder(
mut self,
- label: &'a L,
- subexpr: &'a SubExpr<L, N, E1>,
+ label: &'a Label,
+ subexpr: &'a SubExpr<N, E1>,
) -> Result<(Self::L2, Self::SE2), Self::Error> {
Ok((self.visit_label(label)?, self.visit_subexpr(subexpr)?))
}
@@ -448,7 +460,7 @@ where
fn visit_embed_squash(
self,
embed: &'a E1,
- ) -> Result<SubExpr<L, N, E2>, Self::Error> {
+ ) -> Result<SubExpr<N, E2>, Self::Error> {
Ok((self.0)(embed))
}
@@ -456,7 +468,7 @@ where
// Useful to change the result type, and/or avoid some loss of info
fn visit_resulting_exprf(
result: ExprF<Self::SE2, Self::L2, Self::E2>,
- ) -> Result<SubExpr<L, N, E2>, Self::Error> {
+ ) -> Result<SubExpr<N, E2>, Self::Error> {
// TODO: don't lose note
Ok(SubExpr::from_expr_no_note(result))
}
@@ -464,69 +476,57 @@ where
pub struct UnNoteVisitor;
-impl<'a, 'b, L, N, E>
- ExprFInFallibleVisitor<'a, SubExpr<L, N, E>, SubExpr<L, X, E>, L, L, E, E>
+impl<'a, 'b, N, E>
+ ExprFInFallibleVisitor<'a, SubExpr<N, E>, SubExpr<X, E>, Label, Label, E, E>
for &'b mut UnNoteVisitor
where
- L: Clone + 'a,
E: Clone + 'a,
{
- fn visit_subexpr(
- &mut self,
- subexpr: &'a SubExpr<L, N, E>,
- ) -> SubExpr<L, X, E> {
+ fn visit_subexpr(&mut self, subexpr: &'a SubExpr<N, E>) -> SubExpr<X, E> {
SubExpr::from_expr_no_note(subexpr.as_ref().visit(&mut **self))
}
fn visit_embed(self, embed: &'a E) -> E {
E::clone(embed)
}
- fn visit_label(&mut self, label: &'a L) -> L {
- L::clone(label)
+ fn visit_label(&mut self, label: &'a Label) -> Label {
+ Label::clone(label)
}
}
pub struct NoteAbsurdVisitor;
-impl<'a, 'b, L, N, E>
- ExprFInFallibleVisitor<'a, SubExpr<L, X, E>, SubExpr<L, N, E>, L, L, E, E>
+impl<'a, 'b, N, E>
+ ExprFInFallibleVisitor<'a, SubExpr<X, E>, SubExpr<N, E>, Label, Label, E, E>
for &'b mut NoteAbsurdVisitor
where
- L: Clone + 'a,
E: Clone + 'a,
{
- fn visit_subexpr(
- &mut self,
- subexpr: &'a SubExpr<L, X, E>,
- ) -> SubExpr<L, N, E> {
+ fn visit_subexpr(&mut self, subexpr: &'a SubExpr<X, E>) -> SubExpr<N, E> {
SubExpr::from_expr_no_note(subexpr.as_ref().visit(&mut **self))
}
fn visit_embed(self, embed: &'a E) -> E {
E::clone(embed)
}
- fn visit_label(&mut self, label: &'a L) -> L {
- L::clone(label)
+ fn visit_label(&mut self, label: &'a Label) -> Label {
+ Label::clone(label)
}
}
pub struct EmbedAbsurdVisitor;
-impl<'a, 'b, L, N, E>
- ExprFInFallibleVisitor<'a, SubExpr<L, N, X>, SubExpr<L, N, E>, L, L, X, E>
+impl<'a, 'b, N, E>
+ ExprFInFallibleVisitor<'a, SubExpr<N, X>, SubExpr<N, E>, Label, Label, X, E>
for &'b mut EmbedAbsurdVisitor
where
- L: Clone + 'a,
N: Clone + 'a,
{
- fn visit_subexpr(
- &mut self,
- subexpr: &'a SubExpr<L, N, X>,
- ) -> SubExpr<L, N, E> {
+ fn visit_subexpr(&mut self, subexpr: &'a SubExpr<N, X>) -> SubExpr<N, E> {
subexpr.rewrap(subexpr.as_ref().visit(&mut **self))
}
fn visit_embed(self, embed: &'a X) -> E {
match *embed {}
}
- fn visit_label(&mut self, label: &'a L) -> L {
- L::clone(label)
+ fn visit_label(&mut self, label: &'a Label) -> Label {
+ Label::clone(label)
}
}