summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dhall/src/semantics/phase/mod.rs126
-rw-r--r--serde_dhall/src/lib.rs22
2 files changed, 85 insertions, 63 deletions
diff --git a/dhall/src/semantics/phase/mod.rs b/dhall/src/semantics/phase/mod.rs
index 67cdc91..68c32b2 100644
--- a/dhall/src/semantics/phase/mod.rs
+++ b/dhall/src/semantics/phase/mod.rs
@@ -35,7 +35,7 @@ pub struct Typed(Value);
///
/// Invariant: the contained Typed expression must be in normal form,
#[derive(Debug, Clone)]
-pub struct Normalized(Typed);
+pub struct Normalized(Value);
/// Controls conversion from `Value` to `Expr`
#[derive(Copy, Clone)]
@@ -81,9 +81,8 @@ impl Resolved {
pub fn typecheck(self) -> Result<Typed, TypeError> {
Ok(typecheck::typecheck(self.0)?.into_typed())
}
- pub fn typecheck_with(self, ty: &Typed) -> Result<Typed, TypeError> {
- Ok(typecheck::typecheck_with(self.0, ty.normalize_to_expr())?
- .into_typed())
+ pub fn typecheck_with(self, ty: &Normalized) -> Result<Typed, TypeError> {
+ Ok(typecheck::typecheck_with(self.0, ty.to_expr())?.into_typed())
}
/// Converts a value back to the corresponding AST expression.
pub fn to_expr(&self) -> ResolvedExpr {
@@ -92,39 +91,30 @@ impl Resolved {
pub fn tck_and_normalize_new_flow(&self) -> Result<Normalized, TypeError> {
let val = crate::semantics::tck::typecheck::typecheck(&self.0)?
.normalize_whnf_noenv();
- Ok(Normalized(Typed(val)))
+ Ok(Normalized(val))
}
}
impl Typed {
/// Reduce an expression to its normal form, performing beta reduction
pub fn normalize(mut self) -> Normalized {
- self.normalize_mut();
- Normalized(self)
+ self.0.normalize_mut();
+ Normalized(self.0)
}
- pub(crate) fn from_const(c: Const) -> Self {
- Typed(Value::from_const(c))
- }
- pub(crate) fn from_kind_and_type(v: ValueKind<Value>, t: Typed) -> Self {
- Typed(Value::from_kind_and_type(v, t.into_value()))
- }
pub(crate) fn from_value(th: Value) -> Self {
Typed(th)
}
- pub(crate) fn const_type() -> Self {
- Typed::from_const(Const::Type)
- }
/// Converts a value back to the corresponding AST expression.
- pub fn to_expr(&self) -> ResolvedExpr {
+ pub(crate) fn to_expr(&self) -> ResolvedExpr {
self.0.to_expr(ToExprOptions {
alpha: false,
normalize: false,
})
}
/// Converts a value back to the corresponding AST expression, beta-normalizing in the process.
- pub fn normalize_to_expr(&self) -> NormalizedExpr {
+ pub(crate) fn normalize_to_expr(&self) -> NormalizedExpr {
self.0.to_expr(ToExprOptions {
alpha: false,
normalize: true,
@@ -138,6 +128,34 @@ impl Typed {
normalize: true,
})
}
+ pub(crate) fn into_value(self) -> Value {
+ self.0
+ }
+
+ pub(crate) fn get_type(&self) -> Result<Typed, TypeError> {
+ Ok(self.0.get_type()?.into_typed())
+ }
+}
+
+impl Normalized {
+ pub fn encode(&self) -> Result<Vec<u8>, EncodeError> {
+ binary::encode(&self.to_expr())
+ }
+
+ pub fn to_expr(&self) -> NormalizedExpr {
+ // TODO: do it directly
+ self.to_typed().normalize_to_expr()
+ }
+ pub(crate) fn to_expr_alpha(&self) -> NormalizedExpr {
+ // TODO: do it directly
+ self.to_typed().normalize_to_expr_alpha()
+ }
+ pub(crate) fn to_typed(&self) -> Typed {
+ Typed(self.0.clone())
+ }
+ pub(crate) fn into_typed(self) -> Typed {
+ Typed(self.0)
+ }
pub(crate) fn to_value(&self) -> Value {
self.0.clone()
}
@@ -145,64 +163,58 @@ impl Typed {
self.0
}
- pub(crate) fn normalize_mut(&mut self) {
- self.0.normalize_mut()
+ pub(crate) fn from_const(c: Const) -> Self {
+ Normalized(Value::from_const(c))
}
-
- pub(crate) fn get_type(&self) -> Result<Typed, TypeError> {
- Ok(self.0.get_type()?.into_typed())
+ pub(crate) fn from_kind_and_type(
+ v: ValueKind<Value>,
+ t: Normalized,
+ ) -> Self {
+ Normalized(Value::from_kind_and_type(v, t.into_value()))
+ }
+ pub(crate) fn from_value(th: Value) -> Self {
+ Normalized(th)
+ }
+ pub(crate) fn const_type() -> Self {
+ Normalized::from_const(Const::Type)
}
pub fn make_builtin_type(b: Builtin) -> Self {
- Typed::from_value(Value::from_builtin(b))
+ Normalized::from_value(Value::from_builtin(b))
}
- pub fn make_optional_type(t: Typed) -> Self {
- Typed::from_value(
+ pub fn make_optional_type(t: Normalized) -> Self {
+ Normalized::from_value(
Value::from_builtin(Builtin::Optional).app(t.to_value()),
)
}
- pub fn make_list_type(t: Typed) -> Self {
- Typed::from_value(Value::from_builtin(Builtin::List).app(t.to_value()))
+ pub fn make_list_type(t: Normalized) -> Self {
+ Normalized::from_value(
+ Value::from_builtin(Builtin::List).app(t.to_value()),
+ )
}
pub fn make_record_type(
- kts: impl Iterator<Item = (String, Typed)>,
+ kts: impl Iterator<Item = (String, Normalized)>,
) -> Self {
- Typed::from_kind_and_type(
+ Normalized::from_kind_and_type(
ValueKind::RecordType(
kts.map(|(k, t)| (k.into(), t.into_value())).collect(),
),
- Typed::const_type(),
+ Normalized::const_type(),
)
}
pub fn make_union_type(
- kts: impl Iterator<Item = (String, Option<Typed>)>,
+ kts: impl Iterator<Item = (String, Option<Normalized>)>,
) -> Self {
- Typed::from_kind_and_type(
+ Normalized::from_kind_and_type(
ValueKind::UnionType(
kts.map(|(k, t)| (k.into(), t.map(|t| t.into_value())))
.collect(),
),
- Typed::const_type(),
+ Normalized::const_type(),
)
}
}
-impl Normalized {
- pub fn encode(&self) -> Result<Vec<u8>, EncodeError> {
- binary::encode(&self.to_expr())
- }
-
- pub(crate) fn to_expr(&self) -> NormalizedExpr {
- self.0.normalize_to_expr()
- }
- pub(crate) fn to_expr_alpha(&self) -> NormalizedExpr {
- self.0.normalize_to_expr_alpha()
- }
- pub(crate) fn into_typed(self) -> Typed {
- self.0
- }
-}
-
macro_rules! derive_traits_for_wrapper_struct {
($ty:ident) => {
impl std::cmp::PartialEq for $ty {
@@ -226,7 +238,6 @@ macro_rules! derive_traits_for_wrapper_struct {
derive_traits_for_wrapper_struct!(Parsed);
derive_traits_for_wrapper_struct!(Resolved);
-derive_traits_for_wrapper_struct!(Normalized);
impl std::hash::Hash for Normalized {
fn hash<H>(&self, state: &mut H)
@@ -245,9 +256,20 @@ impl PartialEq for Typed {
self.0 == other.0
}
}
-
impl Display for Typed {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
self.to_expr().fmt(f)
}
}
+
+impl Eq for Normalized {}
+impl PartialEq for Normalized {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+}
+impl Display for Normalized {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
+ self.to_expr().fmt(f)
+ }
+}
diff --git a/serde_dhall/src/lib.rs b/serde_dhall/src/lib.rs
index d65ee7d..334eed9 100644
--- a/serde_dhall/src/lib.rs
+++ b/serde_dhall/src/lib.rs
@@ -181,14 +181,14 @@ pub use value::Value;
// A Dhall value.
#[doc(hidden)]
pub mod value {
- use dhall::semantics::phase::{NormalizedExpr, Parsed, Typed};
+ use dhall::semantics::phase::{Normalized, NormalizedExpr, Parsed};
use dhall::syntax::Builtin;
use super::de::{Error, Result};
/// A Dhall value
#[derive(Debug, Clone, PartialEq, Eq)]
- pub struct Value(Typed);
+ pub struct Value(Normalized);
impl Value {
pub fn from_str(s: &str, ty: Option<&Value>) -> Result<Self> {
@@ -201,38 +201,38 @@ pub mod value {
let resolved = Parsed::parse_str(s)?.resolve()?;
let typed = match ty {
None => resolved.typecheck()?,
- Some(t) => resolved.typecheck_with(t.as_typed())?,
+ Some(t) => resolved.typecheck_with(t.as_normalized())?,
};
- Ok(Value(typed))
+ Ok(Value(typed.normalize()))
}
pub(crate) fn to_expr(&self) -> NormalizedExpr {
- self.0.normalize_to_expr()
+ self.0.to_expr()
}
- pub(crate) fn as_typed(&self) -> &Typed {
+ pub(crate) fn as_normalized(&self) -> &Normalized {
&self.0
}
pub(crate) fn make_builtin_type(b: Builtin) -> Self {
- Value(Typed::make_builtin_type(b))
+ Value(Normalized::make_builtin_type(b))
}
pub(crate) fn make_optional_type(t: Value) -> Self {
- Value(Typed::make_optional_type(t.0))
+ Value(Normalized::make_optional_type(t.0))
}
pub(crate) fn make_list_type(t: Value) -> Self {
- Value(Typed::make_list_type(t.0))
+ Value(Normalized::make_list_type(t.0))
}
// Made public for the StaticType derive macro
#[doc(hidden)]
pub fn make_record_type(
kts: impl Iterator<Item = (String, Value)>,
) -> Self {
- Value(Typed::make_record_type(kts.map(|(k, t)| (k, t.0))))
+ Value(Normalized::make_record_type(kts.map(|(k, t)| (k, t.0))))
}
#[doc(hidden)]
pub fn make_union_type(
kts: impl Iterator<Item = (String, Option<Value>)>,
) -> Self {
- Value(Typed::make_union_type(
+ Value(Normalized::make_union_type(
kts.map(|(k, t)| (k, t.map(|t| t.0))),
))
}