summaryrefslogtreecommitdiff
path: root/dhall/src/syntax/ast/visitor.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dhall/src/syntax/ast/visitor.rs100
1 files changed, 30 insertions, 70 deletions
diff --git a/dhall/src/syntax/ast/visitor.rs b/dhall/src/syntax/ast/visitor.rs
index 0a0c5ef..7244d0a 100644
--- a/dhall/src/syntax/ast/visitor.rs
+++ b/dhall/src/syntax/ast/visitor.rs
@@ -1,22 +1,13 @@
+use itertools::Itertools;
use std::iter::FromIterator;
use crate::syntax::*;
-fn vec<'a, T, U, Err>(
- x: &'a [T],
- f: impl FnMut(&'a T) -> Result<U, Err>,
-) -> Result<Vec<U>, Err> {
- x.iter().map(f).collect()
-}
-
fn opt<'a, T, U, Err>(
x: &'a Option<T>,
f: impl FnOnce(&'a T) -> Result<U, Err>,
) -> Result<Option<U>, Err> {
- Ok(match x {
- Some(x) => Some(f(x)?),
- None => None,
- })
+ x.as_ref().map(f).transpose()
}
fn dupmap<'a, SE1, SE2, T, Err>(
@@ -30,27 +21,6 @@ where
x.into_iter().map(|(k, x)| Ok((k.clone(), f(x)?))).collect()
}
-fn optdupmap<'a, SE1, SE2, T, Err>(
- x: impl IntoIterator<Item = (&'a Label, &'a Option<SE1>)>,
- mut f: impl FnMut(&'a SE1) -> Result<SE2, Err>,
-) -> Result<T, Err>
-where
- SE1: 'a,
- T: FromIterator<(Label, Option<SE2>)>,
-{
- x.into_iter()
- .map(|(k, x)| {
- Ok((
- k.clone(),
- match x {
- Some(x) => Some(f(x)?),
- None => None,
- },
- ))
- })
- .collect()
-}
-
pub fn visit_ref<'a, F, SE1, SE2, Err>(
input: &'a ExprKind<SE1>,
mut f: F,
@@ -60,54 +30,44 @@ where
{
// Can't use closures because of borrowing rules
macro_rules! expr {
+ () => {
+ |e| Ok(expr!(e))
+ };
($e:expr) => {
- f(None, $e)
+ f(None, $e)?
};
($l:expr, $e:expr) => {
- f(Some($l), $e)
+ f(Some($l), $e)?
+ };
+ }
+ macro_rules! opt {
+ () => {
+ |e| Ok(opt!(e))
+ };
+ ($e:expr) => {
+ opt($e, |e| Ok(expr!(e)))?
};
}
use crate::syntax::ExprKind::*;
Ok(match input {
Var(v) => Var(v.clone()),
- Lam(l, t, e) => {
- let t = expr!(t)?;
- let e = expr!(l, e)?;
- Lam(l.clone(), t, e)
- }
- Pi(l, t, e) => {
- let t = expr!(t)?;
- let e = expr!(l, e)?;
- Pi(l.clone(), t, e)
- }
- Let(l, t, a, e) => {
- let t = opt(t, &mut |e| expr!(e))?;
- let a = expr!(a)?;
- let e = expr!(l, e)?;
- Let(l.clone(), t, a, e)
- }
- App(f, a) => App(expr!(f)?, expr!(a)?),
- Annot(x, t) => Annot(expr!(x)?, expr!(t)?),
+ Lam(l, t, e) => Lam(l.clone(), expr!(t), expr!(l, e)),
+ Pi(l, t, e) => Pi(l.clone(), expr!(t), expr!(l, e)),
+ Let(l, t, a, e) => Let(l.clone(), opt!(t), expr!(a), expr!(l, e)),
Const(k) => Const(*k),
- Builtin(v) => Builtin(*v),
Num(n) => Num(n.clone()),
- TextLit(t) => TextLit(t.traverse_ref(|e| expr!(e))?),
- BinOp(o, x, y) => BinOp(*o, expr!(x)?, expr!(y)?),
- BoolIf(b, t, f) => BoolIf(expr!(b)?, expr!(t)?, expr!(f)?),
- EmptyListLit(t) => EmptyListLit(expr!(t)?),
- NEListLit(es) => NEListLit(vec(es, |e| expr!(e))?),
- SomeLit(e) => SomeLit(expr!(e)?),
- RecordType(kts) => RecordType(dupmap(kts, |e| expr!(e))?),
- RecordLit(kvs) => RecordLit(dupmap(kvs, |e| expr!(e))?),
- UnionType(kts) => UnionType(optdupmap(kts, |e| expr!(e))?),
- Merge(x, y, t) => Merge(expr!(x)?, expr!(y)?, opt(t, |e| expr!(e))?),
- ToMap(x, t) => ToMap(expr!(x)?, opt(t, |e| expr!(e))?),
- Field(e, l) => Field(expr!(e)?, l.clone()),
- Projection(e, ls) => Projection(expr!(e)?, ls.clone()),
- ProjectionByExpr(e, x) => ProjectionByExpr(expr!(e)?, expr!(x)?),
- Completion(e, x) => Completion(expr!(e)?, expr!(x)?),
- Assert(e) => Assert(expr!(e)?),
- Import(i) => Import(i.traverse_ref(|e| expr!(e))?),
+ Builtin(v) => Builtin(*v),
+ TextLit(t) => TextLit(t.traverse_ref(expr!())?),
+ SomeLit(e) => SomeLit(expr!(e)),
+ EmptyListLit(t) => EmptyListLit(expr!(t)),
+ NEListLit(es) => NEListLit(es.iter().map(expr!()).try_collect()?),
+ RecordType(kts) => RecordType(dupmap(kts, expr!())?),
+ RecordLit(kvs) => RecordLit(dupmap(kvs, expr!())?),
+ UnionType(kts) => UnionType(dupmap(kts, opt!())?),
+ Op(op) => Op(op.traverse_ref(expr!())?),
+ Annot(x, t) => Annot(expr!(x), expr!(t)),
+ Assert(e) => Assert(expr!(e)),
+ Import(i) => Import(i.traverse_ref(expr!())?),
})
}