diff options
author | Nadrieril | 2019-08-19 23:00:49 +0200 |
---|---|---|
committer | Nadrieril | 2019-08-19 23:00:49 +0200 |
commit | 730f2ebb146792994c7492b6c05f7d09d42cbccf (patch) | |
tree | 9685812388937fdd6c51165804fddf7a1bbf5e6a /dhall/src/core | |
parent | 07a276c1d6ee892b93abbd7a73c78c96d56f4fe7 (diff) |
Merge TypedValue and Value
Diffstat (limited to 'dhall/src/core')
-rw-r--r-- | dhall/src/core/context.rs | 31 | ||||
-rw-r--r-- | dhall/src/core/value.rs | 192 | ||||
-rw-r--r-- | dhall/src/core/valuef.rs | 26 |
3 files changed, 88 insertions, 161 deletions
diff --git a/dhall/src/core/context.rs b/dhall/src/core/context.rs index deabe44..2bf39c5 100644 --- a/dhall/src/core/context.rs +++ b/dhall/src/core/context.rs @@ -3,15 +3,15 @@ use std::rc::Rc; use dhall_syntax::{Label, V}; -use crate::core::value::TypedValue; +use crate::core::value::Value; use crate::core::valuef::ValueF; use crate::core::var::{AlphaVar, Shift, Subst}; use crate::error::TypeError; #[derive(Debug, Clone)] enum CtxItem { - Kept(AlphaVar, TypedValue), - Replaced(TypedValue), + Kept(AlphaVar, Value), + Replaced(Value), } #[derive(Debug, Clone)] @@ -21,21 +21,17 @@ impl TypecheckContext { pub fn new() -> Self { TypecheckContext(Rc::new(Vec::new())) } - pub fn insert_type(&self, x: &Label, t: TypedValue) -> Self { + pub fn insert_type(&self, x: &Label, t: Value) -> Self { let mut vec = self.0.as_ref().clone(); vec.push((x.clone(), CtxItem::Kept(x.into(), t.under_binder(x)))); TypecheckContext(Rc::new(vec)) } - pub fn insert_value( - &self, - x: &Label, - e: TypedValue, - ) -> Result<Self, TypeError> { + pub fn insert_value(&self, x: &Label, e: Value) -> Result<Self, TypeError> { let mut vec = self.0.as_ref().clone(); vec.push((x.clone(), CtxItem::Replaced(e))); Ok(TypecheckContext(Rc::new(vec))) } - pub fn lookup(&self, var: &V<Label>) -> Option<TypedValue> { + pub fn lookup(&self, var: &V<Label>) -> Option<Value> { let mut var = var.clone(); let mut shift_map: HashMap<Label, _> = HashMap::new(); for (l, i) in self.0.iter().rev() { @@ -44,10 +40,7 @@ impl TypecheckContext { let i = i.under_multiple_binders(&shift_map); return Some(match i { CtxItem::Kept(newvar, t) => { - TypedValue::from_valuef_and_type( - ValueF::Var(newvar), - t, - ) + Value::from_valuef_and_type(ValueF::Var(newvar), t) } CtxItem::Replaced(v) => v, }); @@ -101,7 +94,7 @@ impl TypecheckContext { ))) } } - fn subst_shift(&self, var: &AlphaVar, val: &TypedValue) -> Self { + fn subst_shift(&self, var: &AlphaVar, val: &Value) -> Self { self.do_with_var(var, |var, i| Ok::<_, !>(i.subst_shift(&var, val))) .unwrap() } @@ -124,8 +117,8 @@ impl Shift for TypecheckContext { } } -impl Subst<TypedValue> for CtxItem { - fn subst_shift(&self, var: &AlphaVar, val: &TypedValue) -> Self { +impl Subst<Value> for CtxItem { + fn subst_shift(&self, var: &AlphaVar, val: &Value) -> Self { match self { CtxItem::Replaced(e) => CtxItem::Replaced(e.subst_shift(var, val)), CtxItem::Kept(v, t) => match v.shift(-1, var) { @@ -136,8 +129,8 @@ impl Subst<TypedValue> for CtxItem { } } -impl Subst<TypedValue> for TypecheckContext { - fn subst_shift(&self, var: &AlphaVar, val: &TypedValue) -> Self { +impl Subst<Value> for TypecheckContext { + fn subst_shift(&self, var: &AlphaVar, val: &Value) -> Self { self.subst_shift(var, val) } } diff --git a/dhall/src/core/value.rs b/dhall/src/core/value.rs index c4e3831..8573d11 100644 --- a/dhall/src/core/value.rs +++ b/dhall/src/core/value.rs @@ -35,7 +35,7 @@ use Form::{Unevaled, NF, WHNF}; struct ValueInternal { form: Form, value: ValueF, - ty: Option<TypedValue>, + ty: Option<Value>, } /// Stores a possibly unevaluated value. Gets (partially) normalized on-demand, @@ -45,11 +45,6 @@ struct ValueInternal { #[derive(Clone)] pub struct Value(Rc<RefCell<ValueInternal>>); -/// A value that needs to carry a type for typechecking to work. -/// TODO: actually enforce this. -#[derive(Debug, Clone)] -pub struct TypedValue(Value); - impl ValueInternal { fn into_value(self) -> Value { Value(Rc::new(RefCell::new(self))) @@ -96,7 +91,7 @@ impl ValueInternal { } } - fn get_type(&self) -> Result<&TypedValue, TypeError> { + fn get_type(&self) -> Result<&Value, TypeError> { match &self.ty { Some(t) => Ok(t), None => Err(TypeError::new( @@ -116,7 +111,7 @@ impl Value { } .into_value() } - pub(crate) fn from_valuef_and_type(v: ValueF, t: TypedValue) -> Value { + pub(crate) fn from_valuef_and_type(v: ValueF, t: Value) -> Value { ValueInternal { form: Unevaled, value: v, @@ -125,7 +120,57 @@ impl Value { .into_value() } pub(crate) fn from_valuef_simple_type(v: ValueF) -> Value { - Value::from_valuef_and_type(v, TypedValue::from_const(Const::Type)) + Value::from_valuef_and_type(v, Value::from_const(Const::Type)) + } + pub(crate) fn from_const(c: Const) -> Self { + match type_of_const(c) { + Ok(t) => Value::from_valuef_and_type(ValueF::Const(c), t), + Err(_) => Value::from_valuef_untyped(ValueF::Const(c)), + } + } + pub fn const_type() -> Self { + Value::from_const(Const::Type) + } + + pub(crate) fn as_const(&self) -> Option<Const> { + match &*self.as_whnf() { + ValueF::Const(c) => Some(*c), + _ => None, + } + } + + fn as_internal(&self) -> Ref<ValueInternal> { + self.0.borrow() + } + fn as_internal_mut(&self) -> RefMut<ValueInternal> { + self.0.borrow_mut() + } + /// This is what you want if you want to pattern-match on the value. + /// WARNING: drop this ref before normalizing the same value or you will run into BorrowMut + /// panics. + pub(crate) fn as_whnf(&self) -> Ref<ValueF> { + self.do_normalize_whnf(); + Ref::map(self.as_internal(), ValueInternal::as_whnf) + } + + // TODO: rename `normalize_to_expr` + pub(crate) fn to_expr(&self) -> NormalizedSubExpr { + self.as_whnf().normalize_to_expr() + } + // TODO: rename `normalize_to_expr_maybe_alpha` + pub(crate) fn to_expr_alpha(&self) -> NormalizedSubExpr { + self.as_whnf().normalize_to_expr_maybe_alpha(true) + } + // TODO: deprecated + pub(crate) fn to_value(&self) -> Value { + self.clone() + } + /// TODO: cloning a valuef can often be avoided + pub(crate) fn to_whnf(&self) -> ValueF { + self.as_whnf().clone() + } + pub(crate) fn into_typed(self) -> Typed { + Typed::from_value(self) } /// Mutates the contents. If no one else shares this thunk, @@ -138,20 +183,12 @@ impl Value { 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(|vint| vint.normalize_nf()) } - fn as_internal(&self) -> Ref<ValueInternal> { - self.0.borrow() - } - fn as_internal_mut(&self) -> RefMut<ValueInternal> { - self.0.borrow_mut() - } - fn do_normalize_whnf(&self) { let borrow = self.as_internal(); match borrow.form { @@ -163,7 +200,6 @@ impl Value { WHNF | NF => {} } } - fn do_normalize_nf(&self) { let borrow = self.as_internal(); match borrow.form { @@ -176,26 +212,14 @@ impl Value { } } - // WARNING: avoid normalizing any thunk while holding on to this ref - // or you could run into BorrowMut panics + /// WARNING: avoid normalizing any thunk while holding on to this ref + /// or you could run into BorrowMut panics + // TODO: rename to `as_nf` pub(crate) fn normalize_nf(&self) -> Ref<ValueF> { self.do_normalize_nf(); Ref::map(self.as_internal(), ValueInternal::as_nf) } - /// This is what you want if you want to pattern-match on the value. - /// WARNING: drop this ref before normalizing the same value or you will run into BorrowMut - /// panics. - pub(crate) fn as_whnf(&self) -> Ref<ValueF> { - self.do_normalize_whnf(); - Ref::map(self.as_internal(), ValueInternal::as_whnf) - } - - /// TODO: cloning a valuef can often be avoided - pub(crate) fn to_whnf(&self) -> ValueF { - self.as_whnf().clone() - } - pub(crate) fn normalize_to_expr_maybe_alpha( &self, alpha: bool, @@ -211,83 +235,11 @@ impl Value { apply_any(self.clone(), th) } - pub(crate) fn get_type(&self) -> Result<Cow<'_, TypedValue>, TypeError> { + pub(crate) fn get_type(&self) -> Result<Cow<'_, Value>, TypeError> { Ok(Cow::Owned(self.as_internal().get_type()?.clone())) } } -impl TypedValue { - pub fn from_value(th: Value) -> Self { - TypedValue(th) - } - pub(crate) fn from_valuef_untyped(v: ValueF) -> TypedValue { - TypedValue::from_value(Value::from_valuef_untyped(v)) - } - pub(crate) fn from_valuef_and_type(v: ValueF, t: TypedValue) -> Self { - TypedValue(Value::from_valuef_and_type(v, t)) - } - // TODO: do something with the info that the type is Type. Maybe check - // is a type is present ? - pub(crate) fn from_value_simple_type(th: Value) -> Self { - TypedValue::from_value(th) - } - pub(crate) fn from_const(c: Const) -> Self { - match type_of_const(c) { - Ok(t) => TypedValue::from_valuef_and_type(ValueF::Const(c), t), - Err(_) => TypedValue::from_valuef_untyped(ValueF::Const(c)), - } - } - pub fn const_type() -> Self { - TypedValue::from_const(Const::Type) - } - - pub(crate) fn normalize_nf(&self) -> ValueF { - self.0.normalize_nf().clone() - } - - pub(crate) fn normalize_to_expr_maybe_alpha( - &self, - alpha: bool, - ) -> OutputSubExpr { - self.normalize_nf().normalize_to_expr_maybe_alpha(alpha) - } - - /// WARNING: drop this ref before normalizing the same value or you will run into BorrowMut - /// panics. - pub(crate) fn as_whnf(&self) -> Ref<ValueF> { - self.0.as_whnf() - } - pub(crate) fn to_whnf(&self) -> ValueF { - self.0.to_whnf() - } - pub(crate) fn to_expr(&self) -> NormalizedSubExpr { - self.as_whnf().normalize_to_expr() - } - pub(crate) fn to_expr_alpha(&self) -> NormalizedSubExpr { - self.as_whnf().normalize_to_expr_maybe_alpha(true) - } - pub(crate) fn to_value(&self) -> Value { - self.0.clone() - } - pub(crate) fn into_typed(self) -> Typed { - Typed::from_typedvalue(self) - } - pub(crate) fn as_const(&self) -> Option<Const> { - match &*self.as_whnf() { - ValueF::Const(c) => Some(*c), - _ => None, - } - } - - pub(crate) fn normalize_mut(&mut self) { - self.0.normalize_mut() - } - - pub(crate) fn get_type(&self) -> Result<Cow<'_, TypedValue>, TypeError> { - self.0.get_type() - } -} - impl Shift for Value { fn shift(&self, delta: isize, var: &AlphaVar) -> Option<Self> { Some(Value(self.0.shift(delta, var)?)) @@ -304,20 +256,14 @@ impl Shift for ValueInternal { } } -impl Shift for TypedValue { - fn shift(&self, delta: isize, var: &AlphaVar) -> Option<Self> { - Some(TypedValue(self.0.shift(delta, var)?)) - } -} - -impl Subst<TypedValue> for Value { - fn subst_shift(&self, var: &AlphaVar, val: &TypedValue) -> Self { +impl Subst<Value> for Value { + fn subst_shift(&self, var: &AlphaVar, val: &Value) -> Self { Value(self.0.subst_shift(var, val)) } } -impl Subst<TypedValue> for ValueInternal { - fn subst_shift(&self, var: &AlphaVar, val: &TypedValue) -> Self { +impl Subst<Value> for ValueInternal { + fn subst_shift(&self, var: &AlphaVar, val: &Value) -> Self { ValueInternal { // The resulting value may not stay in wnhf after substitution form: Unevaled, @@ -327,12 +273,7 @@ impl Subst<TypedValue> for ValueInternal { } } -impl Subst<TypedValue> for TypedValue { - fn subst_shift(&self, var: &AlphaVar, val: &TypedValue) -> Self { - TypedValue(self.0.subst_shift(var, val)) - } -} - +// TODO: use Rc comparison to shortcut on identical pointers impl std::cmp::PartialEq for Value { fn eq(&self, other: &Self) -> bool { *self.as_whnf() == *other.as_whnf() @@ -340,13 +281,6 @@ impl std::cmp::PartialEq for Value { } impl std::cmp::Eq for Value {} -impl std::cmp::PartialEq for TypedValue { - fn eq(&self, other: &Self) -> bool { - &*self.as_whnf() == &*other.as_whnf() - } -} -impl std::cmp::Eq for TypedValue {} - impl std::fmt::Debug for Value { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let vint: &ValueInternal = &self.as_internal(); diff --git a/dhall/src/core/valuef.rs b/dhall/src/core/valuef.rs index de55d2f..0d2655e 100644 --- a/dhall/src/core/valuef.rs +++ b/dhall/src/core/valuef.rs @@ -5,7 +5,7 @@ use dhall_syntax::{ NaiveDouble, Natural, }; -use crate::core::value::{TypedValue, Value}; +use crate::core::value::Value; use crate::core::var::{AlphaLabel, AlphaVar, Shift, Subst}; use crate::phase::normalize::OutputSubExpr; use crate::phase::Normalized; @@ -18,8 +18,8 @@ use crate::phase::Normalized; #[derive(Debug, Clone, PartialEq, Eq)] pub enum ValueF { /// Closures - Lam(AlphaLabel, TypedValue, Value), - Pi(AlphaLabel, TypedValue, TypedValue), + Lam(AlphaLabel, Value, Value), + Pi(AlphaLabel, Value, Value), // Invariant: the evaluation must not be able to progress further. AppliedBuiltin(Builtin, Vec<Value>), @@ -29,20 +29,20 @@ pub enum ValueF { NaturalLit(Natural), IntegerLit(Integer), DoubleLit(NaiveDouble), - EmptyOptionalLit(TypedValue), + EmptyOptionalLit(Value), NEOptionalLit(Value), // EmptyListLit(t) means `[] : List t`, not `[] : t` - EmptyListLit(TypedValue), + EmptyListLit(Value), NEListLit(Vec<Value>), RecordLit(HashMap<Label, Value>), - RecordType(HashMap<Label, TypedValue>), - UnionType(HashMap<Label, Option<TypedValue>>), - UnionConstructor(Label, HashMap<Label, Option<TypedValue>>), - UnionLit(Label, Value, HashMap<Label, Option<TypedValue>>), + RecordType(HashMap<Label, Value>), + UnionType(HashMap<Label, Option<Value>>), + UnionConstructor(Label, HashMap<Label, Option<Value>>), + UnionLit(Label, Value, HashMap<Label, Option<Value>>), // Invariant: this must not contain interpolations that are themselves TextLits, and // contiguous text values must be merged. TextLit(Vec<InterpolatedTextContents<Value>>), - Equivalence(TypedValue, TypedValue), + Equivalence(Value, Value), // Invariant: this must not contain a value captured by one of the variants above. PartialExpr(ExprF<Value, Normalized>), } @@ -51,7 +51,7 @@ impl ValueF { pub(crate) fn into_value_untyped(self) -> Value { Value::from_valuef_untyped(self) } - pub(crate) fn into_value_with_type(self, t: TypedValue) -> Value { + pub(crate) fn into_value_with_type(self, t: Value) -> Value { Value::from_valuef_and_type(self, t) } pub(crate) fn into_value_simple_type(self) -> Value { @@ -333,8 +333,8 @@ impl Shift for ValueF { } } -impl Subst<TypedValue> for ValueF { - fn subst_shift(&self, var: &AlphaVar, val: &TypedValue) -> Self { +impl Subst<Value> for ValueF { + fn subst_shift(&self, var: &AlphaVar, val: &Value) -> Self { match self { ValueF::AppliedBuiltin(b, args) => { ValueF::AppliedBuiltin(*b, args.subst_shift(var, val)) |