From bbf8d68b0df3ca8b3b8cb7324169f0049736ed89 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 20 Apr 2019 23:52:09 +0200 Subject: Move TypeInternal to typecheck --- dhall/src/expr.rs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index bb1a4e4..03aa966 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -63,6 +63,8 @@ pub struct SimpleType<'a>( ); derive_other_traits!(SimpleType); +pub(crate) use crate::typecheck::TypeInternal; + /// A Dhall expression representing a (possibly higher-kinded) type. /// /// This includes [SimpleType]s but also higher-kinded expressions like @@ -70,14 +72,6 @@ derive_other_traits!(SimpleType); #[derive(Debug, Clone, PartialEq, Eq)] pub struct Type<'a>(pub(crate) TypeInternal<'a>); -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) enum TypeInternal<'a> { - Expr(Box>), - Const(dhall_core::Const), - /// The type of `Sort` - SuperType, -} - // Exposed for the macros #[doc(hidden)] impl<'a> From> for SubExpr { @@ -120,12 +114,6 @@ impl<'a> Normalized<'a> { pub(crate) fn unnote<'b>(self) -> Normalized<'b> { Normalized(self.0, self.1, PhantomData) } - pub(crate) fn into_type(self) -> Type<'a> { - Type(match self.0.as_ref() { - ExprF::Const(c) => TypeInternal::Const(*c), - _ => TypeInternal::Expr(Box::new(self)), - }) - } } #[doc(hidden)] -- cgit v1.2.3 From d1f828961bccf9627ef4fb76ca528f039d180ff7 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 21 Apr 2019 11:30:58 +0200 Subject: Embrace TypeInternal as a semantic value --- dhall/src/expr.rs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index 03aa966..44d1612 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -72,6 +72,15 @@ pub(crate) use crate::typecheck::TypeInternal; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Type<'a>(pub(crate) TypeInternal<'a>); +impl<'a> std::fmt::Display for Type<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + match self.0.clone().into_normalized() { + Ok(e) => e.fmt(f), + Err(_) => write!(f, "SuperType"), + } + } +} + // Exposed for the macros #[doc(hidden)] impl<'a> From> for SubExpr { -- cgit v1.2.3 From a5c94605e29f3694928d6e03de325c0c81fee7b2 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 22 Apr 2019 00:56:47 +0200 Subject: Store context in Typed --- dhall/src/expr.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index 44d1612..1840eba 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -10,6 +10,8 @@ macro_rules! derive_other_traits { } } + impl<'a> std::cmp::Eq for $ty<'a> {} + impl<'a> std::fmt::Display for $ty<'a> { fn fmt( &self, @@ -21,28 +23,29 @@ macro_rules! derive_other_traits { }; } -#[derive(Debug, Clone, Eq)] +#[derive(Debug, Clone)] pub(crate) struct Parsed<'a>( pub(crate) SubExpr, Import>, pub(crate) ImportRoot, ); derive_other_traits!(Parsed); -#[derive(Debug, Clone, Eq)] +#[derive(Debug, Clone)] pub(crate) struct Resolved<'a>( pub(crate) SubExpr, Normalized<'static>>, ); derive_other_traits!(Resolved); -#[derive(Debug, Clone, Eq)] +#[derive(Debug, Clone)] pub(crate) struct Typed<'a>( pub(crate) SubExpr>, pub(crate) Option>, + pub(crate) crate::typecheck::TypecheckContext, pub(crate) PhantomData<&'a ()>, ); derive_other_traits!(Typed); -#[derive(Debug, Clone, Eq)] +#[derive(Debug, Clone)] pub(crate) struct Normalized<'a>( pub(crate) SubExpr, pub(crate) Option>, @@ -56,7 +59,7 @@ derive_other_traits!(Normalized); /// `Bool`, `{ x: Integer }` or `Natural -> Text`. /// /// For a more general notion of "type", see [Type]. -#[derive(Debug, Clone, Eq)] +#[derive(Debug, Clone)] pub struct SimpleType<'a>( pub(crate) SubExpr, pub(crate) PhantomData<&'a ()>, @@ -101,7 +104,12 @@ impl<'a> From> for SimpleType<'a> { #[doc(hidden)] impl<'a> From> for Typed<'a> { fn from(x: Normalized<'a>) -> Typed<'a> { - Typed(x.0.embed_absurd(), x.1, x.2) + Typed( + x.0.embed_absurd(), + x.1, + crate::typecheck::TypecheckContext::new(), + x.2, + ) } } -- cgit v1.2.3 From 60df4ed07a752d256888e6b4449a48bfa43cf79f Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 22 Apr 2019 23:31:42 +0200 Subject: Temporarily simplify functions depending on TypeInternal --- dhall/src/expr.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index 1840eba..94093a9 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -136,12 +136,15 @@ impl<'a> Normalized<'a> { #[doc(hidden)] impl<'a> Type<'a> { pub(crate) fn unnote<'b>(self) -> Type<'b> { - use TypeInternal::*; - Type(match self.0 { - Expr(e) => Expr(Box::new(e.unnote())), - Const(c) => Const(c), - SuperType => SuperType, - }) + // use TypeInternal::*; + // Type(match self.0 { + // Expr(e) => Expr(Box::new(e.unnote())), + // Const(c) => Const(c), + // SuperType => SuperType, + // }) + + // Yes, this is positively horrible. Please forgive me. + unsafe { std::mem::transmute::, Type<'b>>(self) } } } -- cgit v1.2.3 From 2f1fa26abd9c9f2b75d24b18877d3b278f7d2a01 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 23 Apr 2019 14:13:50 +0200 Subject: Avoid duplicating work when matching on Pi types --- dhall/src/expr.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index 94093a9..1c3ec53 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -139,6 +139,7 @@ impl<'a> Type<'a> { // use TypeInternal::*; // Type(match self.0 { // Expr(e) => Expr(Box::new(e.unnote())), + // Pi(ctx, c, x, t, e) => Pi(ctx, c, x, t, e), // Const(c) => Const(c), // SuperType => SuperType, // }) @@ -150,6 +151,14 @@ impl<'a> Type<'a> { impl<'a> SimpleType<'a> { pub(crate) fn into_type(self) -> Type<'a> { - Normalized(self.0, Some(Type::const_type()), PhantomData).into_type() + self.into_type_ctx(&crate::typecheck::TypecheckContext::new()) + } + pub(crate) fn into_type_ctx( + self, + ctx: &crate::typecheck::TypecheckContext, + ) -> Type<'a> { + Normalized(self.0, Some(Type::const_type()), PhantomData) + .into_type_ctx(ctx) + .unwrap() } } -- cgit v1.2.3 From 4b1ad84cb2dad533069d685e212894d517d8fa57 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 23 Apr 2019 17:59:10 +0200 Subject: Silence warnings --- dhall/src/expr.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index 1c3ec53..a548d32 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -114,6 +114,7 @@ impl<'a> From> for Typed<'a> { } #[doc(hidden)] +#[allow(dead_code)] impl<'a> Typed<'a> { pub(crate) fn as_expr(&self) -> &SubExpr> { &self.0 @@ -128,6 +129,7 @@ impl<'a> Normalized<'a> { pub(crate) fn into_expr(self) -> SubExpr { self.0 } + #[allow(dead_code)] pub(crate) fn unnote<'b>(self) -> Normalized<'b> { Normalized(self.0, self.1, PhantomData) } @@ -150,6 +152,7 @@ impl<'a> Type<'a> { } impl<'a> SimpleType<'a> { + #[allow(dead_code)] pub(crate) fn into_type(self) -> Type<'a> { self.into_type_ctx(&crate::typecheck::TypecheckContext::new()) } -- cgit v1.2.3 From a987d01a8d1248f35ba19babb66aebabfad47a6d Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 27 Apr 2019 15:28:16 +0200 Subject: Define new intermediate expression type --- dhall/src/expr.rs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index a548d32..6048928 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -45,6 +45,13 @@ pub(crate) struct Typed<'a>( ); derive_other_traits!(Typed); +#[derive(Debug, Clone)] +pub(crate) struct PartiallyNormalized<'a>( + pub(crate) crate::normalize::WHNF, + pub(crate) Option>, + pub(crate) PhantomData<&'a ()>, +); + #[derive(Debug, Clone)] pub(crate) struct Normalized<'a>( pub(crate) SubExpr, -- cgit v1.2.3 From 290d013e38849e52c35c1bb26c80452590f68e9a Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 27 Apr 2019 19:40:54 +0200 Subject: Builtins --- dhall/src/expr.rs | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index 6048928..d1729a5 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -157,18 +157,3 @@ impl<'a> Type<'a> { unsafe { std::mem::transmute::, Type<'b>>(self) } } } - -impl<'a> SimpleType<'a> { - #[allow(dead_code)] - pub(crate) fn into_type(self) -> Type<'a> { - self.into_type_ctx(&crate::typecheck::TypecheckContext::new()) - } - pub(crate) fn into_type_ctx( - self, - ctx: &crate::typecheck::TypecheckContext, - ) -> Type<'a> { - Normalized(self.0, Some(Type::const_type()), PhantomData) - .into_type_ctx(ctx) - .unwrap() - } -} -- cgit v1.2.3 From a594e3aa376aa4bfef3456d336630f7520f3c28b Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 28 Apr 2019 01:03:12 +0200 Subject: Use PartiallyNormalized throughout typechecking --- dhall/src/expr.rs | 3 --- 1 file changed, 3 deletions(-) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index d1729a5..bde4fe0 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -133,9 +133,6 @@ impl<'a> Normalized<'a> { pub(crate) fn as_expr(&self) -> &SubExpr { &self.0 } - pub(crate) fn into_expr(self) -> SubExpr { - self.0 - } #[allow(dead_code)] pub(crate) fn unnote<'b>(self) -> Normalized<'b> { Normalized(self.0, self.1, PhantomData) -- cgit v1.2.3 From c60d99ddec3653ed10828c91f3e1abf8b78238b0 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 29 Apr 2019 17:13:51 +0200 Subject: Allow representing normal form as a semantic value --- dhall/src/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index bde4fe0..e7beafa 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -47,7 +47,7 @@ derive_other_traits!(Typed); #[derive(Debug, Clone)] pub(crate) struct PartiallyNormalized<'a>( - pub(crate) crate::normalize::WHNF, + pub(crate) crate::normalize::Value, pub(crate) Option>, pub(crate) PhantomData<&'a ()>, ); -- cgit v1.2.3 From 6bb8e618f66df4a955d800d49b3b6863aabd5b41 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 29 Apr 2019 23:28:16 +0200 Subject: Remove NF/WHNF distinction at runtime --- dhall/src/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index e7beafa..b2f2bec 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -47,7 +47,7 @@ derive_other_traits!(Typed); #[derive(Debug, Clone)] pub(crate) struct PartiallyNormalized<'a>( - pub(crate) crate::normalize::Value, + pub(crate) crate::normalize::Value, pub(crate) Option>, pub(crate) PhantomData<&'a ()>, ); -- cgit v1.2.3 From e2626a0bfd4b145e7d54c2150457f57e798ba2f7 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 30 Apr 2019 14:45:25 +0200 Subject: Store a Thunk in Typed --- dhall/src/expr.rs | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index b2f2bec..c794324 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -38,12 +38,10 @@ derive_other_traits!(Resolved); #[derive(Debug, Clone)] pub(crate) struct Typed<'a>( - pub(crate) SubExpr>, + pub(crate) crate::normalize::Thunk, pub(crate) Option>, - pub(crate) crate::typecheck::TypecheckContext, pub(crate) PhantomData<&'a ()>, ); -derive_other_traits!(Typed); #[derive(Debug, Clone)] pub(crate) struct PartiallyNormalized<'a>( @@ -112,22 +110,16 @@ impl<'a> From> for SimpleType<'a> { impl<'a> From> for Typed<'a> { fn from(x: Normalized<'a>) -> Typed<'a> { Typed( - x.0.embed_absurd(), + crate::normalize::Thunk::new( + crate::normalize::NormalizationContext::new(), + x.0.embed_absurd(), + ), x.1, - crate::typecheck::TypecheckContext::new(), x.2, ) } } -#[doc(hidden)] -#[allow(dead_code)] -impl<'a> Typed<'a> { - pub(crate) fn as_expr(&self) -> &SubExpr> { - &self.0 - } -} - #[doc(hidden)] impl<'a> Normalized<'a> { pub(crate) fn as_expr(&self) -> &SubExpr { -- cgit v1.2.3 From 77198a2833297289770867acdaf31db0e2011ea9 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 30 Apr 2019 15:35:13 +0200 Subject: Merge Typed and PartiallyNormalized --- dhall/src/expr.rs | 7 ------- 1 file changed, 7 deletions(-) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index c794324..1ddc4ba 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -43,13 +43,6 @@ pub(crate) struct Typed<'a>( pub(crate) PhantomData<&'a ()>, ); -#[derive(Debug, Clone)] -pub(crate) struct PartiallyNormalized<'a>( - pub(crate) crate::normalize::Value, - pub(crate) Option>, - pub(crate) PhantomData<&'a ()>, -); - #[derive(Debug, Clone)] pub(crate) struct Normalized<'a>( pub(crate) SubExpr, -- cgit v1.2.3 From c13a4881b56bf2f5b2d5d4d0018a48927b45e7e0 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 2 May 2019 14:11:29 +0200 Subject: Store Thunk in Normalized --- dhall/src/expr.rs | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index 1ddc4ba..a753ffd 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -45,11 +45,24 @@ pub(crate) struct Typed<'a>( #[derive(Debug, Clone)] pub(crate) struct Normalized<'a>( - pub(crate) SubExpr, + pub(crate) crate::normalize::Thunk, pub(crate) Option>, pub(crate) PhantomData<&'a ()>, ); -derive_other_traits!(Normalized); + +impl<'a> std::cmp::PartialEq for Normalized<'a> { + fn eq(&self, other: &Self) -> bool { + self.0.normalize_to_expr() == other.0.normalize_to_expr() + } +} + +impl<'a> std::cmp::Eq for Normalized<'a> {} + +impl<'a> std::fmt::Display for Normalized<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + self.0.normalize_to_expr().fmt(f) + } +} /// A Dhall expression representing a simple type. /// @@ -102,21 +115,20 @@ impl<'a> From> for SimpleType<'a> { #[doc(hidden)] impl<'a> From> for Typed<'a> { fn from(x: Normalized<'a>) -> Typed<'a> { - Typed( - crate::normalize::Thunk::new( - crate::normalize::NormalizationContext::new(), - x.0.embed_absurd(), - ), - x.1, - x.2, - ) + Typed(x.0, x.1, x.2) } } -#[doc(hidden)] impl<'a> Normalized<'a> { - pub(crate) fn as_expr(&self) -> &SubExpr { - &self.0 + // Deprecated + pub(crate) fn as_expr(&self) -> SubExpr { + self.0.normalize_to_expr() + } + pub(crate) fn to_expr(&self) -> SubExpr { + self.0.normalize_to_expr() + } + pub(crate) fn to_value(&self) -> crate::normalize::Value { + self.0.normalize_nf().clone() } #[allow(dead_code)] pub(crate) fn unnote<'b>(self) -> Normalized<'b> { -- cgit v1.2.3 From db3ca819283f9bd99d197de464717f0b58b52fe4 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 2 May 2019 17:07:11 +0200 Subject: Instead of possibly nonexistent Type, treat Sort specially --- dhall/src/expr.rs | 158 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 129 insertions(+), 29 deletions(-) (limited to 'dhall/src/expr.rs') diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index a753ffd..4d55f4a 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -1,4 +1,5 @@ use crate::imports::ImportRoot; +use crate::normalize::{Thunk, Value}; use dhall_core::*; use std::marker::PhantomData; @@ -36,23 +37,23 @@ pub(crate) struct Resolved<'a>( ); derive_other_traits!(Resolved); +pub(crate) use self::typed::TypedInternal; + #[derive(Debug, Clone)] pub(crate) struct Typed<'a>( - pub(crate) crate::normalize::Thunk, - pub(crate) Option>, + pub(crate) TypedInternal, pub(crate) PhantomData<&'a ()>, ); #[derive(Debug, Clone)] pub(crate) struct Normalized<'a>( - pub(crate) crate::normalize::Thunk, - pub(crate) Option>, + pub(crate) TypedInternal, pub(crate) PhantomData<&'a ()>, ); impl<'a> std::cmp::PartialEq for Normalized<'a> { fn eq(&self, other: &Self) -> bool { - self.0.normalize_to_expr() == other.0.normalize_to_expr() + self.to_expr() == other.to_expr() } } @@ -60,7 +61,110 @@ impl<'a> std::cmp::Eq for Normalized<'a> {} impl<'a> std::fmt::Display for Normalized<'a> { fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { - self.0.normalize_to_expr().fmt(f) + self.to_expr().fmt(f) + } +} + +mod typed { + use super::{Type, Typed}; + use crate::normalize::{Thunk, Value}; + use crate::typecheck::{ + TypeError, TypeInternal, TypeMessage, TypecheckContext, + }; + use dhall_core::{Const, Label, SubExpr, V, X}; + use std::borrow::Cow; + use std::marker::PhantomData; + + #[derive(Debug, Clone)] + pub(crate) enum TypedInternal { + // The `Sort` higher-kinded type doesn't have a type + Sort, + // Any other value, along with its type + Value(Thunk, Option>), + } + + impl TypedInternal { + pub(crate) fn from_thunk_and_type(th: Thunk, t: Type<'static>) -> Self { + TypedInternal::Value(th, Some(t)) + } + + pub(crate) fn from_thunk_untyped(th: Thunk) -> Self { + TypedInternal::Value(th, None) + } + + // TODO: Avoid cloning if possible + pub(crate) fn to_value(&self) -> Value { + match self { + TypedInternal::Value(th, _) => th.normalize_whnf().clone(), + TypedInternal::Sort => Value::Const(Const::Sort), + } + } + + pub(crate) fn to_expr(&self) -> SubExpr { + self.to_value().normalize_to_expr() + } + + pub(crate) fn to_thunk(&self) -> Thunk { + match self { + TypedInternal::Value(th, _) => th.clone(), + TypedInternal::Sort => { + Thunk::from_whnf(Value::Const(Const::Sort)) + } + } + } + + pub(crate) fn to_type(&self) -> Type<'static> { + match self { + TypedInternal::Sort => Type(TypeInternal::Const(Const::Sort)), + TypedInternal::Value(th, _) => match &*th.normalize_whnf() { + Value::Const(c) => Type(TypeInternal::Const(*c)), + _ => Type(TypeInternal::Typed(Box::new(Typed( + self.clone(), + PhantomData, + )))), + }, + } + } + + pub(crate) fn get_type( + &self, + ) -> Result>, TypeError> { + match self { + TypedInternal::Value(_, Some(t)) => Ok(Cow::Borrowed(t)), + TypedInternal::Value(_, None) => Err(TypeError::new( + &TypecheckContext::new(), + TypeMessage::Untyped, + )), + TypedInternal::Sort => Err(TypeError::new( + &TypecheckContext::new(), + TypeMessage::Sort, + )), + } + } + + pub(crate) fn shift(&self, delta: isize, var: &V