summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
authorNadrieril2020-03-08 21:47:26 +0000
committerNadrieril2020-03-31 21:44:01 +0100
commit94850b720b0171444694452027f1baf947b3c18f (patch)
treeacbc73273f9b0cfd3abd41038ad028c78ffa937c /dhall
parent4e11e882b7d064e9ddf997f9a465206cf6e471aa (diff)
Add SimpleType to mirror SimpleValue
Diffstat (limited to 'dhall')
-rw-r--r--dhall/src/lib.rs6
-rw-r--r--dhall/src/semantics/nze/nir.rs48
-rw-r--r--dhall/src/simple.rs52
3 files changed, 103 insertions, 3 deletions
diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs
index 0be6db3..25196ba 100644
--- a/dhall/src/lib.rs
+++ b/dhall/src/lib.rs
@@ -30,7 +30,7 @@ pub type ParsedExpr = Expr;
pub type DecodedExpr = Expr;
pub type ResolvedExpr = Expr;
pub type NormalizedExpr = Expr;
-pub use crate::simple::{SValKind, SimpleValue};
+pub use crate::simple::{STyKind, SValKind, SimpleType, SimpleValue};
#[derive(Debug, Clone)]
pub struct Parsed(ParsedExpr, ImportLocation);
@@ -146,6 +146,10 @@ impl Normalized {
pub fn to_simple_value(&self) -> Result<SimpleValue, Expr> {
self.0.to_simple_value().ok_or_else(|| self.to_expr())
}
+ /// Converts a value into a SimpleType.
+ pub fn to_simple_type(&self) -> Result<SimpleType, Expr> {
+ self.0.to_simple_type().ok_or_else(|| self.to_expr())
+ }
/// Converts a value back to the corresponding Hir expression.
pub(crate) fn to_hir(&self) -> Hir {
self.0.to_hir_noenv()
diff --git a/dhall/src/semantics/nze/nir.rs b/dhall/src/semantics/nze/nir.rs
index 9e3644c..4615b39 100644
--- a/dhall/src/semantics/nze/nir.rs
+++ b/dhall/src/semantics/nze/nir.rs
@@ -11,7 +11,7 @@ use crate::syntax::{
Span,
};
use crate::{NormalizedExpr, ToExprOptions};
-use crate::{SValKind, SimpleValue};
+use crate::{STyKind, SValKind, SimpleType, SimpleValue};
/// Stores a possibly unevaluated value. Gets (partially) normalized on-demand, sharing computation
/// automatically. Uses a Rc<RefCell> to share computation.
@@ -176,6 +176,52 @@ impl Nir {
_ => return None,
}))
}
+ pub(crate) fn to_simple_type(&self) -> Option<SimpleType> {
+ Some(SimpleType::new(match self.kind() {
+ NirKind::AppliedBuiltin(BuiltinClosure { b, args, .. })
+ if args.is_empty() =>
+ {
+ match b {
+ Builtin::Bool => STyKind::Bool,
+ Builtin::Natural => STyKind::Natural,
+ Builtin::Integer => STyKind::Integer,
+ Builtin::Double => STyKind::Double,
+ Builtin::Text => STyKind::Text,
+ _ => return None,
+ }
+ }
+ NirKind::AppliedBuiltin(BuiltinClosure {
+ b: Builtin::Optional,
+ args,
+ ..
+ }) if args.len() == 1 => {
+ STyKind::Optional(args[0].to_simple_type()?)
+ }
+ NirKind::AppliedBuiltin(BuiltinClosure {
+ b: Builtin::List,
+ args,
+ ..
+ }) if args.len() == 1 => STyKind::List(args[0].to_simple_type()?),
+ NirKind::RecordType(kts) => STyKind::Record(
+ kts.iter()
+ .map(|(k, v)| Some((k.into(), v.to_simple_type()?)))
+ .collect::<Option<_>>()?,
+ ),
+ NirKind::UnionType(kts) => STyKind::Union(
+ kts.iter()
+ .map(|(k, v)| {
+ Some((
+ k.into(),
+ v.as_ref()
+ .map(|v| Ok(v.to_simple_type()?))
+ .transpose()?,
+ ))
+ })
+ .collect::<Option<_>>()?,
+ ),
+ _ => return None,
+ }))
+ }
pub(crate) fn normalize(&self) {
self.0.normalize()
diff --git a/dhall/src/simple.rs b/dhall/src/simple.rs
index 6457291..9d3846e 100644
--- a/dhall/src/simple.rs
+++ b/dhall/src/simple.rs
@@ -1,6 +1,7 @@
use std::collections::BTreeMap;
-use crate::syntax::LitKind;
+use crate::syntax::{Builtin, LitKind};
+use crate::Normalized;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SimpleValue {
@@ -17,6 +18,24 @@ pub enum SValKind {
Text(String),
}
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct SimpleType {
+ kind: Box<STyKind>,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum STyKind {
+ Bool,
+ Natural,
+ Integer,
+ Double,
+ Text,
+ Optional(SimpleType),
+ List(SimpleType),
+ Record(BTreeMap<String, SimpleType>),
+ Union(BTreeMap<String, Option<SimpleType>>),
+}
+
impl SimpleValue {
pub(crate) fn new(kind: SValKind) -> Self {
SimpleValue {
@@ -27,3 +46,34 @@ impl SimpleValue {
self.kind.as_ref()
}
}
+
+impl SimpleType {
+ pub fn new(kind: STyKind) -> Self {
+ SimpleType {
+ kind: Box::new(kind),
+ }
+ }
+ pub fn kind(&self) -> &STyKind {
+ self.kind.as_ref()
+ }
+ pub fn into_normalized(self) -> Normalized {
+ match *self.kind {
+ STyKind::Bool => Normalized::make_builtin_type(Builtin::Bool),
+ STyKind::Natural => Normalized::make_builtin_type(Builtin::Natural),
+ STyKind::Integer => Normalized::make_builtin_type(Builtin::Integer),
+ STyKind::Double => Normalized::make_builtin_type(Builtin::Double),
+ STyKind::Text => Normalized::make_builtin_type(Builtin::Text),
+ STyKind::Optional(t) => {
+ Normalized::make_optional_type(t.into_normalized())
+ }
+ STyKind::List(t) => Normalized::make_list_type(t.into_normalized()),
+ STyKind::Record(kts) => Normalized::make_record_type(
+ kts.into_iter().map(|(k, t)| (k, t.into_normalized())),
+ ),
+ STyKind::Union(kts) => Normalized::make_union_type(
+ kts.into_iter()
+ .map(|(k, t)| (k, t.map(|t| t.into_normalized()))),
+ ),
+ }
+ }
+}