diff options
Diffstat (limited to 'dhall/src')
-rw-r--r-- | dhall/src/lib.rs | 6 | ||||
-rw-r--r-- | dhall/src/semantics/nze/nir.rs | 48 | ||||
-rw-r--r-- | dhall/src/simple.rs | 52 |
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()))), + ), + } + } +} |