diff options
author | Nadrieril | 2020-03-13 14:30:15 +0000 |
---|---|---|
committer | Nadrieril | 2020-03-31 21:44:01 +0100 |
commit | 60425d58151fef142b066d523dc4d5e832070b9c (patch) | |
tree | 331d1b5e9c29f56a72340f17de0a1d6f9f93462e /dhall | |
parent | 94850b720b0171444694452027f1baf947b3c18f (diff) |
Add new Value type in API
Diffstat (limited to '')
-rw-r--r-- | dhall/src/lib.rs | 64 | ||||
-rw-r--r-- | dhall/src/semantics/tck/typecheck.rs | 4 |
2 files changed, 62 insertions, 6 deletions
diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index 25196ba..60b7a0e 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -49,11 +49,18 @@ pub struct Typed { } /// A normalized expression. -/// -/// Invariant: the contained expression must be in normal form, #[derive(Debug, Clone)] pub struct Normalized(Nir); +/// A Dhall value. +#[derive(Debug, Clone)] +pub struct Value { + /// Invariant: in normal form + pub(crate) hir: Hir, + simple_val: Option<SimpleValue>, + simple_ty: Option<SimpleType>, +} + /// Controls conversion from `Nir` to `Expr` #[derive(Copy, Clone, Default)] pub(crate) struct ToExprOptions { @@ -99,8 +106,8 @@ impl Resolved { pub fn typecheck(&self) -> Result<Typed, TypeError> { Ok(Typed::from_tir(typecheck(&self.0)?)) } - pub fn typecheck_with(self, ty: &Normalized) -> Result<Typed, TypeError> { - Ok(Typed::from_tir(typecheck_with(&self.0, ty.to_hir())?)) + pub(crate) fn typecheck_with(self, ty: &Hir) -> Result<Typed, TypeError> { + Ok(Typed::from_tir(typecheck_with(&self.0, ty)?)) } /// Converts a value back to the corresponding AST expression. pub fn to_expr(&self) -> ResolvedExpr { @@ -137,6 +144,13 @@ impl Normalized { pub fn encode(&self) -> Result<Vec<u8>, EncodeError> { binary::encode(&self.to_expr()) } + pub fn to_value(&self) -> Value { + Value { + hir: self.to_hir(), + simple_val: self.0.to_simple_value(), + simple_ty: self.0.to_simple_type(), + } + } /// Converts a value back to the corresponding AST expression. pub fn to_expr(&self) -> NormalizedExpr { @@ -200,6 +214,36 @@ impl Normalized { } } +impl Value { + /// Parse a string into a Value, and optionally ensure that the value matches the provided type + /// annotation. + pub fn from_str_with_annot( + s: &str, + ty: Option<&Self>, + ) -> Result<Self, Error> { + let resolved = Parsed::parse_str(s)?.resolve()?; + let typed = match ty { + None => resolved.typecheck()?, + Some(ty) => resolved.typecheck_with(&ty.hir)?, + }; + Ok(typed.normalize().to_value()) + } + + /// Converts a Value into a SimpleValue. + pub fn to_simple_value(&self) -> Option<SimpleValue> { + self.simple_val.clone() + } + /// Converts a Value into a SimpleType. + pub fn to_simple_type(&self) -> Option<SimpleType> { + self.simple_ty.clone() + } + + /// Converts a value back to the corresponding AST expression. + pub(crate) fn to_expr(&self) -> NormalizedExpr { + self.hir.to_expr(ToExprOptions::default()) + } +} + macro_rules! derive_traits_for_wrapper_struct { ($ty:ident) => { impl std::cmp::PartialEq for $ty { @@ -274,3 +318,15 @@ impl Display for Normalized { self.to_expr().fmt(f) } } + +impl Eq for Value {} +impl PartialEq for Value { + fn eq(&self, other: &Self) -> bool { + self.hir == other.hir + } +} +impl Display for Value { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + self.to_expr().fmt(f) + } +} diff --git a/dhall/src/semantics/tck/typecheck.rs b/dhall/src/semantics/tck/typecheck.rs index 173b76d..9fa33f2 100644 --- a/dhall/src/semantics/tck/typecheck.rs +++ b/dhall/src/semantics/tck/typecheck.rs @@ -808,8 +808,8 @@ pub(crate) fn typecheck<'hir>(hir: &'hir Hir) -> Result<Tir<'hir>, TypeError> { /// Like `typecheck`, but additionally checks that the expression's type matches the provided type. pub(crate) fn typecheck_with<'hir>( hir: &'hir Hir, - ty: Hir, + ty: &Hir, ) -> Result<Tir<'hir>, TypeError> { - let ty = typecheck(&ty)?.eval_to_type(&TyEnv::new())?; + let ty = typecheck(ty)?.eval_to_type(&TyEnv::new())?; type_with(&TyEnv::new(), hir, Some(ty)) } |