summaryrefslogtreecommitdiff
path: root/dhall/src/core
diff options
context:
space:
mode:
authorNadrieril2019-08-19 23:00:49 +0200
committerNadrieril2019-08-19 23:00:49 +0200
commit730f2ebb146792994c7492b6c05f7d09d42cbccf (patch)
tree9685812388937fdd6c51165804fddf7a1bbf5e6a /dhall/src/core
parent07a276c1d6ee892b93abbd7a73c78c96d56f4fe7 (diff)
Merge TypedValue and Value
Diffstat (limited to 'dhall/src/core')
-rw-r--r--dhall/src/core/context.rs31
-rw-r--r--dhall/src/core/value.rs192
-rw-r--r--dhall/src/core/valuef.rs26
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))