summaryrefslogtreecommitdiff
path: root/dhall/src/semantics
diff options
context:
space:
mode:
authorNadrieril2020-03-08 17:11:34 +0000
committerNadrieril2020-03-31 21:44:01 +0100
commit84796fd247eb1a13fcd092a7cd7ec2d587b261bd (patch)
tree1be14161e1181ae058329f4d6bc29cc9c8409aab /dhall/src/semantics
parent5a5aa49e64197899006751db72e404f4b2292d4e (diff)
Add SimpleValue type to facilitate deserialization
Diffstat (limited to '')
-rw-r--r--dhall/src/semantics/nze/nir.rs34
1 files changed, 34 insertions, 0 deletions
diff --git a/dhall/src/semantics/nze/nir.rs b/dhall/src/semantics/nze/nir.rs
index 32ef590..9e3644c 100644
--- a/dhall/src/semantics/nze/nir.rs
+++ b/dhall/src/semantics/nze/nir.rs
@@ -11,6 +11,7 @@ use crate::syntax::{
Span,
};
use crate::{NormalizedExpr, ToExprOptions};
+use crate::{SValKind, SimpleValue};
/// Stores a possibly unevaluated value. Gets (partially) normalized on-demand, sharing computation
/// automatically. Uses a Rc<RefCell> to share computation.
@@ -142,6 +143,39 @@ impl Nir {
pub(crate) fn to_expr_tyenv(&self, tyenv: &TyEnv) -> NormalizedExpr {
self.to_hir(tyenv.as_varenv()).to_expr_tyenv(tyenv)
}
+ pub(crate) fn to_simple_value(&self) -> Option<SimpleValue> {
+ Some(SimpleValue::new(match self.kind() {
+ NirKind::Lit(lit) => SValKind::Lit(lit.clone()),
+ NirKind::TextLit(x) => SValKind::Text(
+ x.as_text()
+ .expect("Normal form should ensure the text is a string"),
+ ),
+ NirKind::EmptyOptionalLit(_) => SValKind::Optional(None),
+ NirKind::NEOptionalLit(x) => {
+ SValKind::Optional(Some(x.to_simple_value()?))
+ }
+ NirKind::EmptyListLit(_) => SValKind::List(vec![]),
+ NirKind::NEListLit(xs) => SValKind::List(
+ xs.iter()
+ .map(|v| v.to_simple_value())
+ .collect::<Option<_>>()?,
+ ),
+ NirKind::RecordLit(kvs) => SValKind::Record(
+ kvs.iter()
+ .map(|(k, v)| Some((k.into(), v.to_simple_value()?)))
+ .collect::<Option<_>>()?,
+ ),
+ NirKind::UnionLit(field, x, _) => {
+ SValKind::Union(field.into(), Some(x.to_simple_value()?))
+ }
+ NirKind::UnionConstructor(field, ty)
+ if ty.get(field).map(|f| f.is_some()) == Some(false) =>
+ {
+ SValKind::Union(field.into(), None)
+ }
+ _ => return None,
+ }))
+ }
pub(crate) fn normalize(&self) {
self.0.normalize()