summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
authorNadrieril2020-03-13 14:30:15 +0000
committerNadrieril2020-03-31 21:44:01 +0100
commit60425d58151fef142b066d523dc4d5e832070b9c (patch)
tree331d1b5e9c29f56a72340f17de0a1d6f9f93462e /dhall
parent94850b720b0171444694452027f1baf947b3c18f (diff)
Add new Value type in API
Diffstat (limited to '')
-rw-r--r--dhall/src/lib.rs64
-rw-r--r--dhall/src/semantics/tck/typecheck.rs4
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))
}