summaryrefslogtreecommitdiff
path: root/dhall_syntax/src/core
diff options
context:
space:
mode:
authorFintanH2019-08-12 22:34:21 +0100
committerFintanH2019-08-12 22:34:21 +0100
commit4a86274878d5ab0ef4f9d8597606226adfd048de (patch)
tree68153eb0e4283740f49042e059402da6eaaf551e /dhall_syntax/src/core
parent405bc3d80c0e169ea74dd12422b9504b7383dab3 (diff)
parent7d17d39005531cb77d8eaf32ed7de8938c66f874 (diff)
Merge remote-tracking branch 'origin/master' into fintan/canonicalize
Diffstat (limited to 'dhall_syntax/src/core')
-rw-r--r--dhall_syntax/src/core/expr.rs58
-rw-r--r--dhall_syntax/src/core/import.rs2
-rw-r--r--dhall_syntax/src/core/map.rs95
-rw-r--r--dhall_syntax/src/core/visitor.rs33
4 files changed, 171 insertions, 17 deletions
diff --git a/dhall_syntax/src/core/expr.rs b/dhall_syntax/src/core/expr.rs
index da9465d..6522cb1 100644
--- a/dhall_syntax/src/core/expr.rs
+++ b/dhall_syntax/src/core/expr.rs
@@ -1,6 +1,6 @@
use std::rc::Rc;
-use crate::map::DupTreeMap;
+use crate::map::{DupTreeMap, DupTreeSet};
use crate::visitor;
use crate::*;
@@ -44,7 +44,7 @@ impl From<NaiveDouble> for f64 {
}
/// Constants for a pure type system
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum Const {
Type,
Kind,
@@ -99,6 +99,8 @@ pub enum BinOp {
BoolEQ,
/// `x != y`
BoolNE,
+ /// x === y
+ Equivalence,
}
/// Built-ins
@@ -119,6 +121,7 @@ pub enum Builtin {
NaturalOdd,
NaturalToInteger,
NaturalShow,
+ NaturalSubtract,
IntegerToDouble,
IntegerShow,
DoubleShow,
@@ -174,6 +177,8 @@ pub enum ExprF<SubExpr, Embed> {
Let(Label, Option<SubExpr>, SubExpr, SubExpr),
/// `x : t`
Annot(SubExpr, SubExpr),
+ /// `assert : t`
+ Assert(SubExpr),
/// Built-in values
Builtin(Builtin),
// Binary operations
@@ -190,14 +195,10 @@ pub enum ExprF<SubExpr, Embed> {
DoubleLit(Double),
/// `"Some ${interpolated} text"`
TextLit(InterpolatedText<SubExpr>),
- /// `[] : List t`
+ /// `[] : t`
EmptyListLit(SubExpr),
/// `[x, y, z]`
NEListLit(Vec<SubExpr>),
- /// Deprecated Optional literal form
- /// `[] : Optional a`
- /// `[x] : Optional a`
- OldOptionalLit(Option<SubExpr>, SubExpr),
/// `Some e`
SomeLit(SubExpr),
/// `{ k1 : t1, k2 : t1 }`
@@ -206,14 +207,12 @@ pub enum ExprF<SubExpr, Embed> {
RecordLit(DupTreeMap<Label, SubExpr>),
/// `< k1 : t1, k2 >`
UnionType(DupTreeMap<Label, Option<SubExpr>>),
- /// `< k1 = t1, k2 : t2, k3 >`
- UnionLit(Label, SubExpr, DupTreeMap<Label, Option<SubExpr>>),
/// `merge x y : t`
Merge(SubExpr, SubExpr, Option<SubExpr>),
/// `e.x`
Field(SubExpr, Label),
/// `e.{ x, y, z }`
- Projection(SubExpr, Vec<Label>),
+ Projection(SubExpr, DupTreeSet<Label>),
/// Embeds an import or the result of resolving the import
Embed(Embed),
}
@@ -311,6 +310,35 @@ impl<N, E> Expr<N, E> {
{
trivial_result(self.traverse_embed(|x| Ok(map_embed(x))))
}
+
+ pub fn traverse_resolve<E2, Err>(
+ &self,
+ visit_embed: impl FnMut(&E) -> Result<E2, Err>,
+ ) -> Result<Expr<N, E2>, Err>
+ where
+ N: Clone,
+ {
+ self.traverse_resolve_with_visitor(&mut visitor::ResolveVisitor(
+ visit_embed,
+ ))
+ }
+
+ pub(crate) fn traverse_resolve_with_visitor<E2, Err, F1>(
+ &self,
+ visitor: &mut visitor::ResolveVisitor<F1>,
+ ) -> Result<Expr<N, E2>, Err>
+ where
+ N: Clone,
+ F1: FnMut(&E) -> Result<E2, Err>,
+ {
+ match self {
+ ExprF::BinOp(BinOp::ImportAlt, l, r) => l
+ .as_ref()
+ .traverse_resolve_with_visitor(visitor)
+ .or(r.as_ref().traverse_resolve_with_visitor(visitor)),
+ _ => self.visit(visitor),
+ }
+ }
}
impl Expr<X, X> {
@@ -387,6 +415,16 @@ impl<N, E> SubExpr<N, E> {
)),
}
}
+
+ pub fn traverse_resolve<E2, Err>(
+ &self,
+ visit_embed: impl FnMut(&E) -> Result<E2, Err>,
+ ) -> Result<SubExpr<N, E2>, Err>
+ where
+ N: Clone,
+ {
+ Ok(self.rewrap(self.as_ref().traverse_resolve(visit_embed)?))
+ }
}
impl SubExpr<X, X> {
diff --git a/dhall_syntax/src/core/import.rs b/dhall_syntax/src/core/import.rs
index ea42dbc..82bb7ff 100644
--- a/dhall_syntax/src/core/import.rs
+++ b/dhall_syntax/src/core/import.rs
@@ -57,6 +57,7 @@ pub struct URL {
pub authority: String,
pub path: File,
pub query: Option<String>,
+ // TODO: implement inline headers
pub headers: Option<Box<ImportHashed>>,
}
@@ -71,6 +72,7 @@ pub enum Scheme {
pub enum ImportMode {
Code,
RawText,
+ Location,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
diff --git a/dhall_syntax/src/core/map.rs b/dhall_syntax/src/core/map.rs
index 63f19cd..6a0ebda 100644
--- a/dhall_syntax/src/core/map.rs
+++ b/dhall_syntax/src/core/map.rs
@@ -1,5 +1,6 @@
/// A sorted map that allows multiple values for each key.
pub use dup_tree_map::DupTreeMap;
+pub use dup_tree_set::DupTreeSet;
mod one_or_more {
use either::Either;
@@ -232,3 +233,97 @@ mod dup_tree_map {
// unsafe impl<K, V> iter::TrustedLen for IntoIter<K, V> {}
}
+
+mod dup_tree_set {
+ use super::DupTreeMap;
+ use std::iter;
+
+ #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+ pub struct DupTreeSet<K> {
+ map: DupTreeMap<K, ()>,
+ }
+
+ pub type Iter<'a, K> = iter::Map<
+ super::dup_tree_map::Iter<'a, K, ()>,
+ for<'b> fn((&'b K, &'b ())) -> &'b K,
+ >;
+ pub type IntoIter<K> =
+ iter::Map<super::dup_tree_map::IntoIter<K, ()>, fn((K, ())) -> K>;
+
+ impl<K> DupTreeSet<K> {
+ pub fn new() -> Self
+ where
+ K: Ord,
+ {
+ DupTreeSet {
+ map: DupTreeMap::new(),
+ }
+ }
+
+ pub fn len(&self) -> usize {
+ self.map.len()
+ }
+ pub fn is_empty(&self) -> bool {
+ self.map.is_empty()
+ }
+
+ pub fn iter(&self) -> Iter<'_, K>
+ where
+ K: Ord,
+ {
+ fn foo<'a, K>((k, ()): (&'a K, &'a ())) -> &'a K {
+ k
+ }
+ self.map.iter().map(foo)
+ }
+ }
+
+ impl<K> Default for DupTreeSet<K>
+ where
+ K: Ord,
+ {
+ fn default() -> Self {
+ Self::new()
+ }
+ }
+
+ impl<K> IntoIterator for DupTreeSet<K>
+ where
+ K: Ord + Clone,
+ {
+ type Item = K;
+ type IntoIter = IntoIter<K>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ fn foo<K>((k, ()): (K, ())) -> K {
+ k
+ }
+ self.map.into_iter().map(foo)
+ }
+ }
+
+ impl<'a, K> IntoIterator for &'a DupTreeSet<K>
+ where
+ K: Ord,
+ {
+ type Item = &'a K;
+ type IntoIter = Iter<'a, K>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
+ }
+ }
+
+ impl<K> iter::FromIterator<K> for DupTreeSet<K>
+ where
+ K: Ord,
+ {
+ fn from_iter<T>(iter: T) -> Self
+ where
+ T: IntoIterator<Item = K>,
+ {
+ let map = iter.into_iter().map(|k| (k, ())).collect();
+ DupTreeSet { map }
+ }
+ }
+}
diff --git a/dhall_syntax/src/core/visitor.rs b/dhall_syntax/src/core/visitor.rs
index 99a9c11..18f76d9 100644
--- a/dhall_syntax/src/core/visitor.rs
+++ b/dhall_syntax/src/core/visitor.rs
@@ -137,17 +137,10 @@ where
),
EmptyListLit(t) => EmptyListLit(v.visit_subexpr(t)?),
NEListLit(es) => NEListLit(vec(es, |e| v.visit_subexpr(e))?),
- OldOptionalLit(x, t) => OldOptionalLit(
- opt(x, |e| v.visit_subexpr(e))?,
- v.visit_subexpr(t)?,
- ),
SomeLit(e) => SomeLit(v.visit_subexpr(e)?),
RecordType(kts) => RecordType(dupmap(kts, v)?),
RecordLit(kvs) => RecordLit(dupmap(kvs, v)?),
UnionType(kts) => UnionType(optdupmap(kts, v)?),
- UnionLit(k, x, kts) => {
- UnionLit(k.clone(), v.visit_subexpr(x)?, optdupmap(kts, v)?)
- }
Merge(x, y, t) => Merge(
v.visit_subexpr(x)?,
v.visit_subexpr(y)?,
@@ -155,6 +148,7 @@ where
),
Field(e, l) => Field(v.visit_subexpr(e)?, l.clone()),
Projection(e, ls) => Projection(v.visit_subexpr(e)?, ls.clone()),
+ Assert(e) => Assert(v.visit_subexpr(e)?),
Embed(a) => return v.visit_embed_squash(a),
})
}
@@ -362,6 +356,31 @@ where
}
}
+pub struct ResolveVisitor<F1>(pub F1);
+
+impl<'a, 'b, N, E, E2, Err, F1>
+ ExprFFallibleVisitor<'a, SubExpr<N, E>, SubExpr<N, E2>, E, E2>
+ for &'b mut ResolveVisitor<F1>
+where
+ N: Clone + 'a,
+ F1: FnMut(&E) -> Result<E2, Err>,
+{
+ type Error = Err;
+
+ fn visit_subexpr(
+ &mut self,
+ subexpr: &'a SubExpr<N, E>,
+ ) -> Result<SubExpr<N, E2>, Self::Error> {
+ Ok(subexpr.rewrap(
+ subexpr
+ .as_ref()
+ .traverse_resolve_with_visitor(&mut **self)?,
+ ))
+ }
+ fn visit_embed(self, embed: &'a E) -> Result<E2, Self::Error> {
+ (self.0)(embed)
+ }
+}
pub struct NoteAbsurdVisitor;
impl<'a, 'b, N, E>