diff options
Diffstat (limited to '')
-rw-r--r-- | dhall/src/syntax/ast/expr.rs | 84 | ||||
-rw-r--r-- | dhall/src/syntax/ast/visitor.rs | 42 | ||||
-rw-r--r-- | dhall/src/syntax/binary/decode.rs | 2 | ||||
l--------- | dhall/src/syntax/text/dhall.abnf | 1 | ||||
-rw-r--r-- | dhall/src/syntax/text/dhall.pest.visibility (renamed from dhall/src/dhall.pest.visibility) | 0 | ||||
-rw-r--r-- | dhall/src/syntax/text/parser.rs | 4 | ||||
-rw-r--r-- | dhall/src/syntax/text/printer.rs | 2 |
7 files changed, 52 insertions, 83 deletions
diff --git a/dhall/src/syntax/ast/expr.rs b/dhall/src/syntax/ast/expr.rs index 68cb524..28a0aee 100644 --- a/dhall/src/syntax/ast/expr.rs +++ b/dhall/src/syntax/ast/expr.rs @@ -24,7 +24,7 @@ pub enum Const { /// The `Int` field is a DeBruijn index. /// See dhall-lang/standard/semantics.md for details #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct V<Label>(pub Label, pub usize); +pub struct V(pub Label, pub usize); // Definition order must match precedence order for // pretty-printing to work correctly @@ -112,7 +112,7 @@ pub enum ExprKind<SubExpr, Embed> { Const(Const), /// `x` /// `x@n` - Var(V<Label>), + Var(V), /// `λ(x : A) -> b` Lam(Label, SubExpr, SubExpr), /// `A -> B` @@ -174,29 +174,38 @@ pub enum ExprKind<SubExpr, Embed> { } impl<SE, E> ExprKind<SE, E> { + pub fn traverse_ref_maybe_binder<'a, SE2, Err>( + &'a self, + visit: impl FnMut(Option<&'a Label>, &'a SE) -> Result<SE2, Err>, + ) -> Result<ExprKind<SE2, E>, Err> + where + E: Clone, + { + visitor::TraverseRefMaybeBinderVisitor(visit).visit(self) + } + pub fn traverse_ref_with_special_handling_of_binders<'a, SE2, Err>( &'a self, - visit_subexpr: impl FnMut(&'a SE) -> Result<SE2, Err>, - visit_under_binder: impl FnOnce(&'a Label, &'a SE) -> Result<SE2, Err>, + mut visit_subexpr: impl FnMut(&'a SE) -> Result<SE2, Err>, + mut visit_under_binder: impl FnMut(&'a Label, &'a SE) -> Result<SE2, Err>, ) -> Result<ExprKind<SE2, E>, Err> where E: Clone, { - visitor::TraverseRefWithBindersVisitor { - visit_subexpr, - visit_under_binder, - } - .visit(self) + self.traverse_ref_maybe_binder(|l, x| match l { + None => visit_subexpr(x), + Some(l) => visit_under_binder(l, x), + }) } - fn traverse_ref<'a, SE2, Err>( + pub(crate) fn traverse_ref<'a, SE2, Err>( &'a self, - visit_subexpr: impl FnMut(&'a SE) -> Result<SE2, Err>, + mut visit_subexpr: impl FnMut(&'a SE) -> Result<SE2, Err>, ) -> Result<ExprKind<SE2, E>, Err> where E: Clone, { - visitor::TraverseRefVisitor { visit_subexpr }.visit(self) + self.traverse_ref_maybe_binder(|_, e| visit_subexpr(e)) } fn traverse_mut<'a, Err>( @@ -206,6 +215,16 @@ impl<SE, E> ExprKind<SE, E> { visitor::TraverseMutVisitor { visit_subexpr }.visit(self) } + pub fn map_ref_maybe_binder<'a, SE2>( + &'a self, + mut map: impl FnMut(Option<&'a Label>, &'a SE) -> SE2, + ) -> ExprKind<SE2, E> + where + E: Clone, + { + trivial_result(self.traverse_ref_maybe_binder(|l, x| Ok(map(l, x)))) + } + pub fn map_ref_with_special_handling_of_binders<'a, SE2>( &'a self, mut map_subexpr: impl FnMut(&'a SE) -> SE2, @@ -214,10 +233,10 @@ impl<SE, E> ExprKind<SE, E> { where E: Clone, { - trivial_result(self.traverse_ref_with_special_handling_of_binders( - |x| Ok(map_subexpr(x)), - |l, x| Ok(map_under_binder(l, x)), - )) + self.map_ref_maybe_binder(|l, x| match l { + None => map_subexpr(x), + Some(l) => map_under_binder(l, x), + }) } pub fn map_ref<'a, SE2>( @@ -227,7 +246,7 @@ impl<SE, E> ExprKind<SE, E> { where E: Clone, { - trivial_result(self.traverse_ref(|x| Ok(map_subexpr(x)))) + self.map_ref_maybe_binder(|_, e| map_subexpr(e)) } pub fn map_mut<'a>(&'a mut self, mut map_subexpr: impl FnMut(&'a mut SE)) { @@ -295,22 +314,6 @@ impl<E> Expr<E> { } } -impl<Label: PartialEq + Clone> V<Label> { - pub fn shift(&self, delta: isize, var: &V<Label>) -> Option<Self> { - let V(x, n) = var; - let V(y, m) = self; - Some(if x == y && n <= m { - V(y.clone(), add_ui(*m, delta)?) - } else { - V(y.clone(), *m) - }) - } - - pub fn over_binder(&self, x: &Label) -> Option<Self> { - self.shift(-1, &V(x.clone(), 0)) - } -} - pub fn trivial_result<T>(x: Result<T, !>) -> T { match x { Ok(x) => x, @@ -318,16 +321,6 @@ pub fn trivial_result<T>(x: Result<T, !>) -> T { } } -/// Add an isize to an usize -/// Returns `None` on over/underflow -fn add_ui(u: usize, i: isize) -> Option<usize> { - Some(if i < 0 { - u.checked_sub(i.checked_neg()? as usize)? - } else { - u.checked_add(i as usize)? - }) -} - impl PartialEq for NaiveDouble { fn eq(&self, other: &Self) -> bool { self.0.to_bits() == other.0.to_bits() @@ -357,9 +350,8 @@ impl From<NaiveDouble> for f64 { } } -/// This is only for the specific `Label` type, not generic -impl From<Label> for V<Label> { - fn from(x: Label) -> V<Label> { +impl From<Label> for V { + fn from(x: Label) -> V { V(x, 0) } } diff --git a/dhall/src/syntax/ast/visitor.rs b/dhall/src/syntax/ast/visitor.rs index 424048b..6a1ce7d 100644 --- a/dhall/src/syntax/ast/visitor.rs +++ b/dhall/src/syntax/ast/visitor.rs @@ -1,6 +1,7 @@ -use crate::syntax::*; use std::iter::FromIterator; +use crate::syntax::*; + /// A visitor trait that can be used to traverse `ExprKind`s. We need this pattern so that Rust lets /// us have as much mutability as we can. /// For example, `traverse_ref_with_special_handling_of_binders` cannot be made using only @@ -295,51 +296,26 @@ where Ok(()) } -pub struct TraverseRefWithBindersVisitor<F1, F2> { - pub visit_subexpr: F1, - pub visit_under_binder: F2, -} +pub struct TraverseRefMaybeBinderVisitor<F>(pub F); -impl<'a, SE, E, SE2, Err, F1, F2> ExprKindVisitor<'a, SE, SE2, E, E> - for TraverseRefWithBindersVisitor<F1, F2> +impl<'a, SE, E, SE2, Err, F> ExprKindVisitor<'a, SE, SE2, E, E> + for TraverseRefMaybeBinderVisitor<F> where SE: 'a, E: 'a + Clone, - F1: FnMut(&'a SE) -> Result<SE2, Err>, - F2: FnOnce(&'a Label, &'a SE) -> Result<SE2, Err>, + F: FnMut(Option<&'a Label>, &'a SE) -> Result<SE2, Err>, { type Error = Err; fn visit_subexpr(&mut self, subexpr: &'a SE) -> Result<SE2, Self::Error> { - (self.visit_subexpr)(subexpr) + (self.0)(None, subexpr) } fn visit_subexpr_under_binder( - self, + mut self, label: &'a Label, subexpr: &'a SE, ) -> Result<SE2, Self::Error> { - (self.visit_under_binder)(label, subexpr) - } - fn visit_embed(self, embed: &'a E) -> Result<E, Self::Error> { - Ok(embed.clone()) - } -} - -pub struct TraverseRefVisitor<F1> { - pub visit_subexpr: F1, -} - -impl<'a, SE, E, SE2, Err, F1> ExprKindVisitor<'a, SE, SE2, E, E> - for TraverseRefVisitor<F1> -where - SE: 'a, - E: 'a + Clone, - F1: FnMut(&'a SE) -> Result<SE2, Err>, -{ - type Error = Err; - - fn visit_subexpr(&mut self, subexpr: &'a SE) -> Result<SE2, Self::Error> { - (self.visit_subexpr)(subexpr) + (self.0)(Some(label), subexpr) } fn visit_embed(self, embed: &'a E) -> Result<E, Self::Error> { Ok(embed.clone()) diff --git a/dhall/src/syntax/binary/decode.rs b/dhall/src/syntax/binary/decode.rs index c18deb5..52b699c 100644 --- a/dhall/src/syntax/binary/decode.rs +++ b/dhall/src/syntax/binary/decode.rs @@ -3,13 +3,13 @@ use serde_cbor::value::value as cbor; use std::iter::FromIterator; use crate::error::DecodeError; -use crate::semantics::phase::DecodedExpr; use crate::syntax; use crate::syntax::{ Expr, ExprKind, FilePath, FilePrefix, Hash, ImportLocation, ImportMode, Integer, InterpolatedText, Label, Natural, Scheme, Span, UnspannedExpr, URL, V, }; +use crate::DecodedExpr; pub(crate) fn decode(data: &[u8]) -> Result<DecodedExpr, DecodeError> { match serde_cbor::de::from_slice(data) { diff --git a/dhall/src/syntax/text/dhall.abnf b/dhall/src/syntax/text/dhall.abnf new file mode 120000 index 0000000..4a95034 --- /dev/null +++ b/dhall/src/syntax/text/dhall.abnf @@ -0,0 +1 @@ +../../../../dhall-lang/standard/dhall.abnf
\ No newline at end of file diff --git a/dhall/src/dhall.pest.visibility b/dhall/src/syntax/text/dhall.pest.visibility index 03a000b..03a000b 100644 --- a/dhall/src/dhall.pest.visibility +++ b/dhall/src/syntax/text/dhall.pest.visibility diff --git a/dhall/src/syntax/text/parser.rs b/dhall/src/syntax/text/parser.rs index ef1471f..2ec63e2 100644 --- a/dhall/src/syntax/text/parser.rs +++ b/dhall/src/syntax/text/parser.rs @@ -5,7 +5,6 @@ use std::rc::Rc; use pest_consume::{match_nodes, Parser}; -use crate::semantics::phase::Normalized; use crate::syntax; use crate::syntax::map::{DupTreeMap, DupTreeSet}; use crate::syntax::ExprKind::*; @@ -14,6 +13,7 @@ use crate::syntax::{ InterpolatedText, InterpolatedTextContents, Label, NaiveDouble, Natural, Scheme, Span, UnspannedExpr, URL, V, }; +use crate::Normalized; // This file consumes the parse tree generated by pest and turns it into // our own AST. All those custom macros should eventually moved into @@ -422,7 +422,7 @@ impl DhallParser { )) } - fn variable(input: ParseInput) -> ParseResult<V<Label>> { + fn variable(input: ParseInput) -> ParseResult<V> { Ok(match_nodes!(input.into_children(); [label(l), natural_literal(idx)] => V(l, idx), [label(l)] => V(l, 0), diff --git a/dhall/src/syntax/text/printer.rs b/dhall/src/syntax/text/printer.rs index 96f4c2a..06dd70f 100644 --- a/dhall/src/syntax/text/printer.rs +++ b/dhall/src/syntax/text/printer.rs @@ -496,7 +496,7 @@ impl Display for Scheme { } } -impl<Label: Display> Display for V<Label> { +impl Display for V { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { let V(x, n) = self; x.fmt(f)?; |