summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
authorNadrieril2019-08-18 23:17:03 +0200
committerNadrieril2019-08-18 23:17:03 +0200
commite70da4c0e9ee2354d757f19f1712f5b04f7acc99 (patch)
treef3929e5dcc74c7038417949000f5ae4e343af526 /dhall
parentc7d9a8659214a228963ea40d76e361bbc08129bb (diff)
Merge ValueInternal and TypedValueInternal
Diffstat (limited to 'dhall')
-rw-r--r--dhall/src/core/value.rs190
1 files changed, 79 insertions, 111 deletions
diff --git a/dhall/src/core/value.rs b/dhall/src/core/value.rs
index 19976af..ef43e3e 100644
--- a/dhall/src/core/value.rs
+++ b/dhall/src/core/value.rs
@@ -29,17 +29,13 @@ enum Form {
use Form::{Unevaled, NF, WHNF};
#[derive(Debug, Clone)]
-enum ValueInternal {
- /// Partially normalized value.
- /// Invariant: if the marker is `WHNF`, the value must be in Weak Head Normal Form
- /// Invariant: if the marker is `NF`, the value must be fully normalized
- ValueF(Form, ValueF),
-}
-
-#[derive(Debug)]
-struct TypedValueInternal {
- internal: ValueInternal,
- typ: Option<Type>,
+/// Partially normalized value.
+/// Invariant: if `form` is `WHNF`, `value` must be in Weak Head Normal Form
+/// Invariant: if `form` is `NF`, `value` must be fully normalized
+struct ValueInternal {
+ form: Form,
+ value: ValueF,
+ ty: Option<Type>,
}
/// Stores a possibly unevaluated value. Gets (partially) normalized on-demand,
@@ -47,7 +43,7 @@ struct TypedValueInternal {
/// Can optionally store a Type from typechecking to preserve type information through
/// normalization.
#[derive(Clone)]
-pub struct Value(Rc<RefCell<TypedValueInternal>>);
+pub struct Value(Rc<RefCell<ValueInternal>>);
/// A value that needs to carry a type for typechecking to work.
/// TODO: actually enforce this.
@@ -55,72 +51,54 @@ pub struct Value(Rc<RefCell<TypedValueInternal>>);
pub struct TypedValue(Value);
impl ValueInternal {
- fn into_value(self, t: Option<Type>) -> Value {
- TypedValueInternal {
- internal: self,
- typ: t,
- }
- .into_value()
+ fn into_value(self) -> Value {
+ Value(Rc::new(RefCell::new(self)))
}
fn normalize_whnf(&mut self) {
- take_mut::take(self, |vint| match vint {
- ValueInternal::ValueF(Unevaled, v) => {
- ValueInternal::ValueF(WHNF, normalize_whnf(v))
- }
+ take_mut::take(self, |vint| match &vint.form {
+ Unevaled => ValueInternal {
+ form: WHNF,
+ value: normalize_whnf(vint.value),
+ ty: vint.ty,
+ },
// Already in WHNF
- vint @ ValueInternal::ValueF(WHNF, _)
- | vint @ ValueInternal::ValueF(NF, _) => vint,
+ WHNF | NF => vint,
})
}
-
fn normalize_nf(&mut self) {
- match self {
- ValueInternal::ValueF(Unevaled, _) => {
+ match self.form {
+ Unevaled => {
self.normalize_whnf();
self.normalize_nf();
}
- ValueInternal::ValueF(f @ WHNF, v) => {
- v.normalize_mut();
- *f = NF;
+ WHNF => {
+ self.value.normalize_mut();
+ self.form = NF;
}
// Already in NF
- ValueInternal::ValueF(NF, _) => {}
+ NF => {}
}
}
- // Always use normalize_whnf before
+ /// Always use normalize_whnf before
fn as_whnf(&self) -> &ValueF {
- match self {
- ValueInternal::ValueF(Unevaled, _) => unreachable!(),
- ValueInternal::ValueF(_, v) => v,
+ match self.form {
+ Unevaled => unreachable!(),
+ _ => &self.value,
}
}
-
- // Always use normalize_nf before
+ /// Always use normalize_nf before
fn as_nf(&self) -> &ValueF {
- match self {
- ValueInternal::ValueF(Unevaled, _)
- | ValueInternal::ValueF(WHNF, _) => unreachable!(),
- ValueInternal::ValueF(NF, v) => v,
+ match self.form {
+ Unevaled | WHNF => unreachable!(),
+ NF => &self.value,
}
}
-}
-impl TypedValueInternal {
- fn into_value(self) -> Value {
- Value(Rc::new(RefCell::new(self)))
- }
- fn as_internal(&self) -> &ValueInternal {
- &self.internal
- }
- fn as_internal_mut(&mut self) -> &mut ValueInternal {
- &mut self.internal
- }
-
- fn get_type(&self) -> Result<Type, TypeError> {
- match &self.typ {
- Some(t) => Ok(t.clone()),
+ fn get_type(&self) -> Result<&Type, TypeError> {
+ match &self.ty {
+ Some(t) => Ok(t),
None => Err(TypeError::new(
&TypecheckContext::new(),
TypeMessage::Untyped,
@@ -131,70 +109,80 @@ impl TypedValueInternal {
impl Value {
pub(crate) fn from_valuef(v: ValueF) -> Value {
- ValueInternal::ValueF(Unevaled, v).into_value(None)
+ ValueInternal {
+ form: Unevaled,
+ value: v,
+ ty: None,
+ }
+ .into_value()
}
pub(crate) fn from_valuef_and_type(v: ValueF, t: Type) -> Value {
- ValueInternal::ValueF(Unevaled, v).into_value(Some(t))
+ ValueInternal {
+ form: Unevaled,
+ value: v,
+ ty: Some(t),
+ }
+ .into_value()
}
pub(crate) fn from_partial_expr(e: ExprF<Value, Normalized>) -> Value {
Value::from_valuef(ValueF::PartialExpr(e))
}
+ // TODO: avoid using this function
pub(crate) fn with_type(self, t: Type) -> Value {
- self.as_internal().clone().into_value(Some(t))
+ let vint = self.as_internal();
+ ValueInternal {
+ form: vint.form,
+ value: vint.value.clone(),
+ ty: Some(t),
+ }
+ .into_value()
}
/// Mutates the contents. If no one else shares this thunk,
/// mutates directly, thus avoiding a RefCell lock.
- fn mutate_internal(&mut self, f: impl FnOnce(&mut TypedValueInternal)) {
+ fn mutate_internal(&mut self, f: impl FnOnce(&mut ValueInternal)) {
match Rc::get_mut(&mut self.0) {
// Mutate directly if sole owner
Some(refcell) => f(RefCell::get_mut(refcell)),
// Otherwise mutate through the refcell
- None => f(&mut self.as_tinternal_mut()),
+ None => f(&mut self.as_internal_mut()),
}
}
/// Normalizes contents to normal form; faster than `normalize_nf` if
/// no one else shares this thunk.
pub(crate) fn normalize_mut(&mut self) {
- self.mutate_internal(|i| i.as_internal_mut().normalize_nf())
+ self.mutate_internal(|vint| vint.normalize_nf())
}
- fn as_tinternal(&self) -> Ref<TypedValueInternal> {
- self.0.borrow()
- }
- fn as_tinternal_mut(&mut self) -> RefMut<TypedValueInternal> {
- self.0.borrow_mut()
- }
fn as_internal(&self) -> Ref<ValueInternal> {
- Ref::map(self.as_tinternal(), TypedValueInternal::as_internal)
+ self.0.borrow()
}
fn as_internal_mut(&self) -> RefMut<ValueInternal> {
- RefMut::map(self.0.borrow_mut(), TypedValueInternal::as_internal_mut)
+ self.0.borrow_mut()
}
fn do_normalize_whnf(&self) {
let borrow = self.as_internal();
- match &*borrow {
- ValueInternal::ValueF(Unevaled, _) => {
+ match borrow.form {
+ Unevaled => {
drop(borrow);
self.as_internal_mut().normalize_whnf();
}
// Already at least in WHNF
- ValueInternal::ValueF(WHNF, _) | ValueInternal::ValueF(NF, _) => {}
+ WHNF | NF => {}
}
}
fn do_normalize_nf(&self) {
let borrow = self.as_internal();
- match &*borrow {
- ValueInternal::ValueF(Unevaled, _)
- | ValueInternal::ValueF(WHNF, _) => {
+ match borrow.form {
+ Unevaled | WHNF => {
drop(borrow);
self.as_internal_mut().normalize_nf();
}
// Already in NF
- ValueInternal::ValueF(NF, _) => {}
+ NF => {}
}
}
@@ -240,7 +228,7 @@ impl Value {
}
pub(crate) fn get_type(&self) -> Result<Cow<'_, Type>, TypeError> {
- Ok(Cow::Owned(self.as_tinternal().get_type()?))
+ Ok(Cow::Owned(self.as_internal().get_type()?.clone()))
}
}
@@ -330,10 +318,10 @@ impl Shift for Value {
impl Shift for ValueInternal {
fn shift(&self, delta: isize, var: &AlphaVar) -> Option<Self> {
- Some(match self {
- ValueInternal::ValueF(f, v) => {
- ValueInternal::ValueF(*f, v.shift(delta, var)?)
- }
+ Some(ValueInternal {
+ form: self.form,
+ value: self.value.shift(delta, var)?,
+ ty: self.ty.shift(delta, var)?,
})
}
}
@@ -344,15 +332,6 @@ impl Shift for TypedValue {
}
}
-impl Shift for TypedValueInternal {
- fn shift(&self, delta: isize, var: &AlphaVar) -> Option<Self> {
- Some(TypedValueInternal {
- internal: self.internal.shift(delta, var)?,
- typ: self.typ.shift(delta, var)?,
- })
- }
-}
-
impl Subst<Typed> for Value {
fn subst_shift(&self, var: &AlphaVar, val: &Typed) -> Self {
Value(self.0.subst_shift(var, val))
@@ -361,20 +340,11 @@ impl Subst<Typed> for Value {
impl Subst<Typed> for ValueInternal {
fn subst_shift(&self, var: &AlphaVar, val: &Typed) -> Self {
- match self {
- ValueInternal::ValueF(_, v) => {
- // The resulting value may not stay in wnhf after substitution
- ValueInternal::ValueF(Unevaled, v.subst_shift(var, val))
- }
- }
- }
-}
-
-impl Subst<Typed> for TypedValueInternal {
- fn subst_shift(&self, var: &AlphaVar, val: &Typed) -> Self {
- TypedValueInternal {
- internal: self.internal.subst_shift(var, val),
- typ: self.typ.subst_shift(var, val),
+ ValueInternal {
+ // The resulting value may not stay in wnhf after substitution
+ form: Unevaled,
+ value: self.value.subst_shift(var, val),
+ ty: self.ty.subst_shift(var, val),
}
}
}
@@ -401,11 +371,9 @@ impl std::cmp::Eq for TypedValue {}
impl std::fmt::Debug for Value {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- let b: &ValueInternal = &self.as_internal();
- match b {
- ValueInternal::ValueF(f, v) => {
- fmt.debug_tuple(&format!("Value@{:?}", f)).field(v).finish()
- }
- }
+ let vint: &ValueInternal = &self.as_internal();
+ fmt.debug_tuple(&format!("Value@{:?}", &vint.form))
+ .field(&vint.value)
+ .finish()
}
}