From 5197c26c23edd6c499f8e0f8a239fe4393b2e3d2 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 30 Jan 2020 17:09:16 +0000 Subject: Move main API to lib.rs --- dhall/src/lib.rs | 244 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) (limited to 'dhall/src/lib.rs') diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index 62a1b27..cbf3ceb 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -16,3 +16,247 @@ mod tests; pub mod error; pub mod semantics; pub mod syntax; + +use std::fmt::Display; +use std::path::Path; + +use crate::error::{EncodeError, Error, ImportError, TypeError}; +use crate::semantics::phase::parse; +use crate::semantics::phase::resolve; +use crate::semantics::phase::resolve::ImportRoot; +use crate::semantics::{typecheck, typecheck_with, TyExpr, Value, ValueKind}; +use crate::syntax::binary; +use crate::syntax::{Builtin, Const, Expr}; + +pub type ParsedExpr = Expr; +pub type DecodedExpr = Expr; +pub type ResolvedExpr = Expr; +pub type NormalizedExpr = Expr; + +#[derive(Debug, Clone)] +pub struct Parsed(ParsedExpr, ImportRoot); + +/// An expression where all imports have been resolved +/// +/// Invariant: there must be no `Import` nodes or `ImportAlt` operations left. +#[derive(Debug, Clone)] +pub struct Resolved(ResolvedExpr); + +/// A typed expression +#[derive(Debug, Clone)] +pub struct Typed(TyExpr); + +/// A normalized expression. +/// +/// Invariant: the contained Typed expression must be in normal form, +#[derive(Debug, Clone)] +pub struct Normalized(Value); + +/// Controls conversion from `Value` to `Expr` +#[derive(Copy, Clone)] +pub(crate) struct ToExprOptions { + /// Whether to convert all variables to `_` + pub(crate) alpha: bool, + /// Whether to normalize before converting + pub(crate) normalize: bool, +} + +impl Parsed { + pub fn parse_file(f: &Path) -> Result { + parse::parse_file(f) + } + pub fn parse_str(s: &str) -> Result { + parse::parse_str(s) + } + pub fn parse_binary_file(f: &Path) -> Result { + parse::parse_binary_file(f) + } + pub fn parse_binary(data: &[u8]) -> Result { + parse::parse_binary(data) + } + + pub fn resolve(self) -> Result { + resolve::resolve(self) + } + pub fn skip_resolve(self) -> Result { + resolve::skip_resolve_expr(self) + } + + pub fn encode(&self) -> Result, EncodeError> { + binary::encode(&self.0) + } + + /// Converts a value back to the corresponding AST expression. + pub fn to_expr(&self) -> ParsedExpr { + self.0.clone() + } +} + +impl Resolved { + pub fn typecheck(&self) -> Result { + Ok(Typed(typecheck(&self.0)?)) + } + pub fn typecheck_with(self, ty: &Normalized) -> Result { + Ok(Typed(typecheck_with(&self.0, ty.to_expr())?)) + } + /// Converts a value back to the corresponding AST expression. + pub fn to_expr(&self) -> ResolvedExpr { + self.0.clone() + } +} + +impl Typed { + /// Reduce an expression to its normal form, performing beta reduction + pub fn normalize(&self) -> Normalized { + Normalized(self.0.rec_eval_closed_expr()) + } + + /// Converts a value back to the corresponding AST expression. + fn to_expr(&self) -> ResolvedExpr { + self.0.to_expr(ToExprOptions { + alpha: false, + normalize: false, + }) + } + + pub(crate) fn get_type(&self) -> Result { + Ok(Normalized(self.0.get_type()?)) + } +} + +impl Normalized { + pub fn encode(&self) -> Result, EncodeError> { + binary::encode(&self.to_expr()) + } + + /// Converts a value back to the corresponding AST expression. + pub fn to_expr(&self) -> NormalizedExpr { + self.0.to_expr(ToExprOptions { + alpha: false, + normalize: false, + }) + } + /// Converts a value back to the corresponding AST expression, alpha-normalizing in the process. + pub(crate) fn to_expr_alpha(&self) -> NormalizedExpr { + self.0.to_expr(ToExprOptions { + alpha: true, + normalize: false, + }) + } + pub(crate) fn to_value(&self) -> Value { + self.0.clone() + } + pub(crate) fn into_value(self) -> Value { + self.0 + } + + pub(crate) fn from_const(c: Const) -> Self { + Normalized(Value::from_const(c)) + } + pub(crate) fn from_kind_and_type( + v: ValueKind, + 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 { + Normalized::from_value(Value::from_builtin(b)) + } + 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: Normalized) -> Self { + Normalized::from_value( + Value::from_builtin(Builtin::List).app(t.to_value()), + ) + } + pub fn make_record_type( + kts: impl Iterator, + ) -> Self { + Normalized::from_kind_and_type( + ValueKind::RecordType( + kts.map(|(k, t)| (k.into(), t.into_value())).collect(), + ), + Normalized::const_type(), + ) + } + pub fn make_union_type( + kts: impl Iterator)>, + ) -> Self { + Normalized::from_kind_and_type( + ValueKind::UnionType( + kts.map(|(k, t)| (k.into(), t.map(|t| t.into_value()))) + .collect(), + ), + Normalized::const_type(), + ) + } +} + +macro_rules! derive_traits_for_wrapper_struct { + ($ty:ident) => { + impl std::cmp::PartialEq for $ty { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } + } + + impl std::cmp::Eq for $ty {} + + impl std::fmt::Display for $ty { + fn fmt( + &self, + f: &mut std::fmt::Formatter, + ) -> Result<(), std::fmt::Error> { + self.0.fmt(f) + } + } + }; +} + +derive_traits_for_wrapper_struct!(Parsed); +derive_traits_for_wrapper_struct!(Resolved); + +impl std::hash::Hash for Normalized { + fn hash(&self, state: &mut H) + where + H: std::hash::Hasher, + { + if let Ok(vec) = self.encode() { + vec.hash(state) + } + } +} + +impl Eq for Typed {} +impl PartialEq for Typed { + fn eq(&self, other: &Self) -> bool { + self.normalize() == other.normalize() + } +} +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) + } +} -- cgit v1.2.3 From 8ff022fa2cec34bc1d46ac3655d0c3d228ef893c Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 30 Jan 2020 17:16:25 +0000 Subject: Move parse and resolve up a level --- dhall/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'dhall/src/lib.rs') diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index cbf3ceb..e9f8aa3 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -21,9 +21,9 @@ use std::fmt::Display; use std::path::Path; use crate::error::{EncodeError, Error, ImportError, TypeError}; -use crate::semantics::phase::parse; -use crate::semantics::phase::resolve; -use crate::semantics::phase::resolve::ImportRoot; +use crate::semantics::parse; +use crate::semantics::resolve; +use crate::semantics::resolve::ImportRoot; use crate::semantics::{typecheck, typecheck_with, TyExpr, Value, ValueKind}; use crate::syntax::binary; use crate::syntax::{Builtin, Const, Expr}; -- cgit v1.2.3 From 0749482ad2ab9340fb45a2fe2997d2ea04516d75 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 30 Jan 2020 18:06:53 +0000 Subject: Remove type parameter from ValueKind --- dhall/src/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'dhall/src/lib.rs') diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index e9f8aa3..dbf1fc0 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -153,10 +153,7 @@ impl Normalized { pub(crate) fn from_const(c: Const) -> Self { Normalized(Value::from_const(c)) } - pub(crate) fn from_kind_and_type( - v: ValueKind, - t: Normalized, - ) -> Self { + pub(crate) fn from_kind_and_type(v: ValueKind, t: Normalized) -> Self { Normalized(Value::from_kind_and_type(v, t.into_value())) } pub(crate) fn from_value(th: Value) -> Self { -- cgit v1.2.3